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として復元される)。