VB XML手册1:用XML常量进行XML转换

Categories: VB
Tags:
Comments: No Comments
Published on: 2008 年 10 月 31 日
[原文作者]Doug Rothaus
 
     我正在做一个关于用Visual Basic XML Literals取代XSLT转换的博客,我发现这个博客将会很长,所以,Avner Aharoni 和我谈了之后决定像几个月前我们做的LINQ操作指南一样把它分为多个条目并成一个系列。
 
     先介绍一下VB XML的操作指南。这个操作指南介绍了如何在Visual Basic中使用XML Literals的快速而简单的方法。在很多情况下,我们将会参考有着直接或者是相近功能的XSLTXPath你将会发现用XML Literals来转换和翻译XML是一件快速而简单的事情,XML的轴属性,和LINQXML,这一切都是从Visual Basic 2008开始的。
 
    首先介绍如何用XML LiteralsLINQ执行简单的XML转换。每个例子都用了一个嵌入式表达,从LINQ队列或者其他的资源,比如属性或函数中返回一组XML Literals,只需几行Visual Basic代码就能完成整个XSLT的转换。
 
     先看第一个例子,我们用了一个包含SQL ServerXML文件(AWContacts.xml)。每一个<Contact>标签都有一个<EmailAddress>的子标签,下面的代码创建了一个新的在代码中含有e-mail地址的XML文件。

Imports <xmlns="http://SampleSchema/AWContacts">
 
Public Class XMLCookbook
 Private Sub Recipe1()
   Dim xmlDoc = XDocument.Load("AWContacts.xml")
 
   Dim emailDoc = <?xml version="1.0"?>
                   <EmailAddresses>
                       <%= xmlDoc.<Contacts>.<Contact>.<EmailAddress> %>
                  </EmailAddresses>
 
   emailDoc.Save("EmailAddresses.xml")
 End Sub
End Class

 

     如果用XSLT进行转换,我们将要花费更多。在这里,你只是用了一个Visual Basic创建一个template函数,然后用XML Literals加载并保存XML,就像创建一个新的XML文件一样。XML Child Axisproperty引用了一组<EmailAddress>子标签,你也可以用embedded expressionXML文件中增加标签而不是<xsl:copy-of>,这样你就不用XSLTXpath转换这个文件。接下来我们看一个XSLTVisual Basic代码)转换的例子。

Recipe1.xslt
<?xmlversion=1.0?>
<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:aw="http://SampleSchema/AWContacts"
 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">
    <EmailAddresses>
      <xsl:copy-ofselect="aw:Contact/aw:EmailAddress"/>
    </EmailAddresses>
 </xsl:template>
</xsl:stylesheet>
Recipe1_XSLT Visual Basic Code
 
Public Class XMLCookbook
    Sub Recipe1_XSLT()
        Dim xslTransform As New System.Xml.Xsl.XslCompiledTransform
        xslTransform.Load("recipe1.xslt")
 
        Dim reader = Xml.XmlReader.Create("AWContacts.xml")
        Dim sw As New System.IO.StreamWriter("Recipe1.xml")
        Dim writer = Xml.XmlWriter.Create(sw)
 
        xslTransform.Transform(reader, writer)
        sw.Close()
    End Sub
End Class

 

     这里的XSLT转换出两端大量的代码,让我们花费了大量的工作创建VB版本。在Visual BasicXML命名空间比XSLT1.0)简单,我可以为XML元素定义一个缺省的XML命名空间而不需要特别的去定义一个XML命名空间。
     还有重要的一点,在Visual Basic能为XML Literals提供只能的支持,通过增加在博客附件中的schema文件然后继承这些schemas,我得到一个完整的XML子元素的列表,欲了解更多的信息,请参考XML Intellisense in Visual Basic.
 
     使用LINQ
 
     然后,你可以用LINQ在转换中增加一些查询功能。在XSLT中,你可以很轻易的用 <xsl:for-each>循环和 <xsl:if>判断来完成这个功能
 
     例如,在源文件中,每一个<Contact>标签都有一个<EmailPromotion>的子标签,这个标签确定了是否希望从该公司接收e-mail。下面的代码给出了一个例子,但是只包含了接受e-mail许可的e-mail地址。
 Dim promoList = <?xml version="1.0"?>

                  <EmailPromotionList>
                      <%= From contact In xmlDoc.<Contacts>.<Contact> _
                          Where contact.<EmailPromotion>.Value > 0 _
                          Select contact.<EmailAddress> %>
                  </EmailPromotionList>

     下面是相比较的XSLT代码:

 <xsl:templatematch="aw:Contacts">

    <EmailAddresses>
      <xsl:for-eachselect="aw:Contact">
        <xsl:iftest="aw:EmailPromotion &gt; 0">
          <xsl:copy-ofselect="aw:EmailAddress"/>
        </xsl:if>
      </xsl:for-each>
    </EmailAddresses>
 </xsl:template>

      上一个例子中,我们进一步的把源XML文件转化成一种新的格式。也可以用一个LINQ查询返回一组XMLLiterals。用嵌入式表达复制源文件中的值到新的XML Literal的元素或属性中。例如,新的文件将把<EmailAddress>替换为<Email>,原本<EmailPromotion>包含的信息转换为<Email>中的属性。

 
 Dim transformList = <?xml version="1.0"?>

                      <EmailPromotionList>
                          <%= From contact In xmlDoc.<Contacts>.<Contact> _
                              Where contact.<EmailPromotion>.Value > 0 _
                              Select <Email
                                       promotion=<%= contact.<EmailPromotion>.Value %>>
                                       <%= contact.<EmailAddress>.Value %>
                                     </Email> %>
                      </EmailPromotionList>

     下面是相比较的XSLT代码:

 <xsl:templatematch="aw:Contacts">

    <EmailPromotionList>
      <xsl:for-eachselect="aw:Contact">
        <xsl:iftest="aw:EmailPromotion &gt; 0">
          <Email>
            <xsl:attributename="promotion">
              <xsl:value-ofselect="aw:EmailPromotion"/>
            </xsl:attribute>
            <xsl:value-ofselect="aw:EmailAddress"/>
          </Email>
        </xsl:if>
      </xsl:for-each>
    </EmailPromotionList>
 </xsl:template>

      总之,我们看到如何使用Visual Basic, XML LiteralsLINQ来代替<xsl:copy-of>, <xsl:for-each>, <xsl:template>, <xsl:if>, <xsl:value-of> <xsl:attribute>标签,并用XML轴属性代替Xpath创造一个强大又简单的XML转换工具。

请看更多。。。。
No Comments - Leave a comment

Leave a comment


Welcome , today is 星期六, 2017 年 02 月 25 日