VB XML 手册2:子代和父代

Categories: VB
Comments: 1 Comment
Published on: 2008 年 10 月 28 日
[原文作者]Doug Rothaus
 
 
   这个手册主要是讲,在XML文件中怎样使用Visual BasicXML轴属性和LINQ toXML对象访问子和父元素。
 
 
   Visual Basic提供XML轴属性,可以很容易的引用子节点和标记。这是使用XML经常会遇到的情况。你可能会需要引用下一级元素在XML的数据层次上的不同层级上出现。那样的话,你可以使用XML 子代轴属性
 
   XML子代轴属性是用三个跟随着你想引用的XML元素的周期来定义的。例如,在手册1中用到的AdventureWorks contacts source文件中(你可以从手册1下载这个XML文件和相关的模式)。里面有个<AdditonalContactInfo>元素,包括了关于联系方式例如电话号码,发货和帐单地址等等的信息。在<AdditionalContactInfo>元素里面的电话号码可以出现在这个元素值里面的任何位置。最终,你就可以用XML子代轴属性来引用电话号码这个元素。例如:
 
Dim xmlDoc = XDocument.Load("AWContacts.xml")
 
‘ Return all descendant <telephoneNumber> elements
Dim telephoneNumbers = _
 xmlDoc.<Contacts>.<Contact>.<aci:AdditionalContactInfo><act:telephoneNumber>
 
   XML子代轴属性返回XML数据层次中所有符合元素的集合。我们看一个更加完整的例子。下面的方法用XML子代轴属性返回一串联系名字和电话号码。
 
Imports <xmlns="http://SampleSchema/AWContacts">
Imports <xmlns:s="sample-output">
Imports <xmlns:aci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo">
Imports <xmlns:act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
 
Public Class Recipe2
 
 Public Function GetPhoneNumbers(ByVal xmlDoc As XDocument) As XElement
    Return <s:ContactPhoneNumbers>
             <%= From contact In xmlDoc.<Contacts>.<Contact> _
                 Where contact.<aci:AdditionalContactInfo><act:telephoneNumber>.<act:number>.Count > 0 _
                 Select <s:Contact>
                          <s:Name><%= contact.<FirstName>.Value & " " & _
                                      contact.<LastName>.Value %></s:Name>
                          <s:PhoneNumbers>
                            <%= From number In _
                                contact.<aci:AdditionalContactInfo><act:telephoneNumber>.<act:number> _
                                Select <s:Number><%= number.Value %></s:Number> _
                            %>
                          </s:PhoneNumbers>
                        </s:Contact> _
             %>
           </s:ContactPhoneNumbers>
 End Function
End Class
 
XSLT中,同样传输是这样的:
 
<?xmlversion=1.0?>
<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:aw="http://SampleSchema/AWContacts"
 xmlns:s="sample-output"
 xmlns:aci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo"
 xmlns:crm="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactRecord"
 xmlns:act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<xsl:outputmethod="xml"indent="yes" />
 
 <xsl:templatematch="aw:Contacts">
    <s:ContactPhoneNumbers>
      <xsl:apply-templatesselect="aw:Contact" />
    </s:ContactPhoneNumbers>
 </xsl:template>
 
 <xsl:templatematch="aw:Contact">
    <xsl:iftest="count(aci:AdditionalContactInfo//act:telephoneNumber/act:number) > 0">
      <s:Contact>
        <s:Name>
          <xsl:value-ofselect="aw:FirstName"/>
          <xsl:text> </xsl:text>
          <xsl:value-ofselect="aw:LastName"/>
        </s:Name>
        <xsl:apply-templatesselect="aci:AdditionalContactInfo" />
      </s:Contact>
    </xsl:if>
 </xsl:template>
 
 <xsl:templatematch="aci:AdditionalContactInfo">
    <s:PhoneNumbers>
      <xsl:for-eachselect=".//act:telephoneNumber/act:number">
        <s:Number>
          <xsl:value-ofselect="."/>
        </s:Number>
      </xsl:for-each>
    </s:PhoneNumbers>
 </xsl:template>
 
</xsl:stylesheet>
 
   一个比较重要的需要注意的是,当子元素的位置总是一样的时候就不应该用XML子代轴属性。如果用XML 子轴属性去引用XML数据层次中的特定位置,你的代码会比使用XML子代轴属性去搜索整个XML数据层次中符合的项执行起来好很多。
 
父代
 
   XML轴属性使向下搜索XML数据层次快并且简单。然而,如果你想向上搜索XML数据层次呢?那样的话,你可以用XNode类的Ancestors方法。因为XML直接把LINQ to XML类的功能暴露出来,你可以用那些LINQ to XML类附带的功能。
 
   Ancestors()这个方法在XML数据层次中向上搜索那些符合给出元素名字的元素。传给Ancestors方法的元素的名字必须包括元素XML命名空间。可以用GetXmlNamespace operator返回基于给出的XMLprefix的命名空间。对于默认的XML命名空间,调用GetXmlNamespace操作不传入prefix。如果你在同样的XML命名空间中搜索一个已经引用的元素,可以用Name.Namespace属性访问已经引用的元素的命名空间。
 
   例如,下面的例子从AdventureWorks Contacts得到一串<telephoneNumber>元素(实际上,任何一个类型的phoneNumberType定义在ContactType.xsd文件里面),然后返回一串电话号码和跟电话号码相关的名字。这个例子调用Ancestors()方法去向上搜索XML数据层次中的<Contact>节点。
 
Imports <xmlns="http://SampleSchema/AWContacts">
Imports <xmlns:s="sample-output">
Imports <xmlns:aci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo">
Imports <xmlns:act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
 
Public Class Recipe2
 
 Public Function GetPhoneList(ByVal numberList As IEnumerable(Of XElement)) As XElement
    Return <s:PhoneNumberList>
             <%= From number In numberList _
                 Let contact = number.Ancestors(GetXmlNamespace() + "Contact") _
                 Select <s:PhoneNumber>
                          <s:Number type=<%= number.Name.LocalName %>>
                            <%= number.<act:number>.Value %>
                          </s:Number>
                          <s:Owner><%= contact.<FirstName>.Value & " " & _
                                       contact.<LastName>.Value %></s:Owner>
                      </s:PhoneNumber> _
             %>
           </s:PhoneNumberList>
 End Function
End Class
 
XSLT中,同样的传输是这样的:
 
<?xmlversion=1.0?>
<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:aw="http://SampleSchema/AWContacts"
 xmlns:s="sample-output"
 xmlns:aci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo"
 xmlns:crm="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactRecord"
 xmlns:act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
<xsl:outputmethod="xml"indent="yes" />
 
 <xsl:templatematch="aw:Contacts">
    <s:PhoneNumberList>
      <xsl:apply-templatesselect="aw:Contact//act:telephoneNumber" />
    </s:PhoneNumberList>
 </xsl:template>
 
 <xsl:templatematch="aw:Contact//act:telephoneNumber">
    <s:PhoneNumber>
      <s:Number>
        <xsl:attributename="type">
          <xsl:value-ofselect="name()" />
        </xsl:attribute>
        <xsl:value-ofselect="./act:number"/>
      </s:Number>
      <s:Owner>
        <xsl:value-ofselect="ancestor::aw:Contact/aw:FirstName"/>
        <xsl:text> </xsl:text>
        <xsl:value-ofselect="ancestor::aw:Contact/aw:LastName"/>
      </s:Owner>
    </s:PhoneNumber>
 </xsl:template>
</xsl:stylesheet>
1 Comment - Leave a comment
  1. quoted on 匿名说道:

    VB XML 手册2:子代和父代

Leave a comment


Welcome , today is 星期五, 2017 年 04 月 28 日