ものがたり(旧)

atsushieno.hatenablog.com に続く

JsonReaderWriterFactoryについて

.NET 3.5のSystem.ServiceModel.Web.dllには、JSONをサポートするXmlReader/XmlWriterがある。しかし、これが実際にはどういう振る舞いを見せるかは、どこにも書かれていない。というわけで個人的な説明をまとめてみる。

  • 内容の種類にかかわらず、document elementに該当するのは root というラッパー要素になる。
  • 内容の種類は、ラッパー要素にtype属性として表現する。値はJSON型名のみ
  • objectとarray以外はtext contentになる
  • 要素名を規定するのはobjectとarrayのみ
    • objectの内容は全て要素となり、項目名をラッパー要素名とし、値をその内容とする
    • arrayの内容は全て要素となり、"item"をラッパー要素名とし、値をその内容とする
  • objectの内容の最初の項目名が "__type" である場合は、これはDataContractJsonSerializerで利用されるランタイム型を示す属性となる。値の書式は Type.Name:#Type.Namespace (例: Int32:#System)((これはDataContractJsonSerializerでしか特別な意味を持たないが、__type を属性として扱うのはXmlReaderである。__type が内容の最初の項目として出てこなかった場合は、オブジェクトの通常の子要素として処理される。

例:

"123"
<root type="string">123</root>
123
<root type="number">123</root>
{}
<root type="object"></root>
{ "foo" : "bar" }
<root type="object"><foo type="string">bar</foo></root>
[1, true, "A"]
<root type="array"><item type="number">1</item><item type="boolean">true</item><item type="string">A</item></root>

2/3 ちょいっと訂正(foo -> foo type="string")

JsonReaderWriterFactoryから生成したXmlReaderで読み込む時のポイントは、string型にせよnumber型にせよ、type属性を考慮しないと、正しく復元できないということかな("123"と123は、Textノードだけ見るとどちらも単に123として復元される)。