ものがたり(旧)

atsushieno.hatenablog.com に続く

CoreCLR XmlReader reduction

ひさしぶりにせせこましいネタを書いてみよう。

CoreCLR (Silverlight用の、2.1プロファイルのやつ)のXmlReaderは、それまでのXmlReaderに比べていらん機能が削られている。今日Miguelが、moonlightでXPS Viewerが動かねーんだと言ってきた中で書いてあったので気付いたのが、次の3つがXmlReaderから消え去っているということだ。

  • HasValue
  • ReadAttributeValue()
  • ResolveEntity()

ResolveEntity()は、カレントノードがEntityReferenceである場合に、このメソッドを呼び出すことでその実体参照を展開するという振る舞いが期待されているもので、ほとんどのアプリケーションでは、そんなの最初から展開していてくれという存在だ。(SAXのようにカスタムEntityResolverとして実装しなかったのは、XmlReaderがpull parserであることと、実装の内部にアクセスできるようなメカニズムを他の方法で上手く提供できなかったのが理由であろう。)

ReadAttributeValue()は、属性値ノードが複数に分かれている時にのみ必要だったもので、僕が今すぐ思いつく存在意義としては、XmlNodeReaderで、XmlAttributeのChildNodesが複数あった場合、くらいしか無い*1。XmlDocumentは2.1プロファイルには存在しないので、実質的な存在意義ももう無い。GetAttribute()やMoveTo*Attribute() + get_Value()で十分だ。

HasValueは、実際にはXmlReaderクラスの内部で最適化目的で使用されていたであろう程度の存在意義しかないと思う。ほとんどのXmlReaderアプリケーションでは、特定の要素または属性に限定して値を取得するなんてことはしないので、最適化のメリットはほとんど無かったはずだ。

ReadAttributeValue()が無くなったのは特に良いと思う。これがあるだけでSgmlReaderなどXmlReaderの派生クラスの多くがバグだらけになっていたわけだから。*2

まあ、どうでもいい話かな。XmlReaderの派生クラスを作る人なんて、どうせほとんど居ないだろうし。

*1:属性値にEntityReferenceが含まれる場合も思いつくが、その展開はEntityHandlingの値に依存してRead()の時点で処理される

*2:全てのプロパティ/メソッドについて、element/text/comment/piのstateと、attributeのstateと、attribute valueのstateの3つを考慮しなければならなかったのが、2つですむようになる