レシピ 3」では、混在 XML コンテンツを XML 子孫軸プロパティReplaceWith メソッドを使用して操作する 1 つの方法を紹介しました。これは ID 変換の 1 つの方法であり、今後の投稿で別の方法を取り上げます。完全に機能する ID 変換のためには、「レシピ 3」で説明していない重要な機能が必要になります。それは、要素の内部 XML のコピーという概念です。要素の内部 XML は、Nodes プロパティから取得します。

  

「レシピ 3」では、AdventureWorks サンプル ドキュメントの電子メール オブジェクトを HTML ドキュメントのハイパーリンクに変換し、ID 変換を実行することにより元の書式を保持しました。ただし、「レシピ 3」では話を簡単にするため、<eMailAddress> 要素 (ContactTypes.xsd スキーマ ファイルにあります) のスキーマでは、電子メール アドレスを含む <eMail> 要素と、呼び出しのときに電子メールの代わりに使用する電話番号などの追加指示用の <SpecialInstructions> 要素の両方が許されるという事実を除外しました。<SpecialInstructions> 要素には、ContactTypes.xsd で識別される他のすべての要素を格納できます。<eMailAddress> 要素のすべての情報を含めるには、特別な命令もすべて含める必要があります (メモ : XML ドキュメントと関連スキーマは「レシピ 1」の投稿からダウンロードできます)。

  

<eMail> 要素には電子メール アドレスの値だけが含まれるので、電子メール アドレスから <eMail> 要素への変換は簡単です。しかし、<SpecialInstructions> 要素には値だけでなくサブ要素も含まれる可能性があるので、それほど簡単ではありません。<SpecialInstructions> 要素の Value を組み込んでいる場合、要素内で見つかるテキストを取得しますが、要素内で見つかる XML はすべて削除されます。これを "要素の内部テキスト" とも呼びます。

  

System.Xml 名前空間のクラスを理解していれば、この動作もすぐに理解できます。このソリューションは、内部テキスト (Value プロパティ) ではなく、要素の内部 XML を組み込むためのものです。System.Xml クラスは InnerText プロパティと InnerXml プロパティの両方を公開しますが、LINQ to XML では公開しません。内部テキストは Value プロパティから返され、内部 XML は Nodes プロパティから返されます。この違いはなぜでしょうか。InnerXml プロパティは XML の文字列を返し、この文字列は XML オブジェクトに再解析される必要があります。Nodes プロパティは LINQ to XML オブジェクトのコレクションを返します。このコレクションは全体として操作したり、XML リテラルに組み込んだりすることができるので、Nodes プロパティは XML 変換の強力なツールとなります。

  

そこで、このことをすべて考慮しながら、ある例の Value (内部テキスト) プロパティと Nodes (内部 XML) プロパティの両方を見ていきましょう。ここに、XML ソースを HTML に変換する TransformEmail という関数 (テンプレート) があります。電子メール アドレスは Value プロパティと、含まれる可能性のあるすべての特別な命令に対して HTML を埋め込むための GetSpecialInstructions 関数の呼び出しによって取得されます。GetSpecialInstructions メソッドは <SpecialInstructions> 要素の HTML マークアップと内部 XML を返します。<SpecialInstructions> 要素には、テキストなどが混在したマークアップまたは他の XML が含まれることがあるためです。

  

    Private Sub TransformEmail(ByVal email As XElement)

        Dim emailHtml = <div class="Email">

                                            <a href=<%= "mailto:" & email.<act:eMailAddress>.Value %>>

                                                <%= email.<act:eMailAddress>.Value %>

                                            </a>&#32;

                                            <%= GetSpecialInstructions(email.<act:SpecialInstructions>) %>

                                        </div>

  

       email.ReplaceWith(emailHtml)

    End Sub

  

    Private Function GetSpecialInstructions( _

        ByVal instructions As IEnumerable(Of XElement)) As IEnumerable(Of XElement)

  

        If instructions IsNot Nothing Then _

            Return From instruction In instructions _

                          Select <span class="SpecialInstructions">

                                            <%= instruction.Nodes %>

                                        </span>

  

        Return Nothing

    End Function

  

投稿 : 2008 年 5 月 1 日午後 4 時 50 分

 

VB チームの Web ログ - http://blogs.msdn.com/vbteam/archive/2008/05/01/vb-xml-cookbook-recipe-4-inner-xml-doug-rothaus.aspx (英語) より