【问题标题】:XML 2 XML using XSLTXML 2 XML 使用 XSLT
【发布时间】:2011-04-28 00:37:25
【问题描述】:

我在 w3schools 学习了 XSLT 和 XPath,但这并不是我想要的。 只有关于转换 XSLT 2 HTML 的示例,这很容易,但是我需要一个 XML 2 XML 转换并且找不到带有示例的好教程...我下载了 MSXSL.exe 但找不到有关使用它的示例转换 XML... 任何人都可以写一个样本吗? 我有 customers.xml 之类的:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--Customers table from Northwind database-->
<Customers>
  <Customer CustomerID="ALFKI">
    <CompanyName>Alfreds Futterkiste</CompanyName>
    <Country>Germany</Country>
    <Orders>
      <Order OrderID="10643">
        <ShipCity>Berlin</ShipCity>
      </Order>
      <Order OrderID="10692">
        <ShipCity>Berlin</ShipCity>
      </Order>
      <Order OrderID="10702">
        <ShipCity>Berlin</ShipCity>
      </Order>
      <Order OrderID="10835">
        <ShipCity>Berlin</ShipCity>
      </Order>
      <Order OrderID="10952">
        <ShipCity>Berlin</ShipCity>
      </Order>
      <Order OrderID="11011">
        <ShipCity>Berlin</ShipCity>
      </Order>
    </Orders>
  </Customer>
  <Customer CustomerID="ANATR">
    <CompanyName>Ana Trujillo Emparedados y helados</CompanyName>
    <Country>Mexico</Country>
    <Orders>
      <Order OrderID="10308">
        <ShipCity>México D.F.</ShipCity>
      </Order>
      <Order OrderID="10625">
        <ShipCity>México D.F.</ShipCity>
      </Order>
      <Order OrderID="10759">
        <ShipCity>México D.F.</ShipCity>
      </Order>
      <Order OrderID="10926">
        <ShipCity>México D.F.</ShipCity>
      </Order>
    </Orders>
  </Customer>
</Customers>

并尝试生成另一个仅包含“国家”节点的 XML。 怎么写?

【问题讨论】:

  • 好问题,+1。请参阅我的答案以获得两种解决方案。 :)

标签: xml xslt transformation


【解决方案1】:

完全一样,只需要相应地使用output元素的method属性即可。

【讨论】:

    【解决方案2】:

    这样的事情应该可以工作......

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
    
      <xsl:template match="/">
        <Countries>
          <xsl:apply-templates select="//Country" mode="copyNode" />
        </Countries>
      </xsl:template>
    
      <xsl:template match="@* | node()" mode="copyNode">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()" mode="copyNode"/>
        </xsl:copy>
      </xsl:template>
    </xsl:stylesheet>
    

    ...这是结果...

    <?xml version="1.0" encoding="utf-8"?>
    <Countries>
      <Country>Germany</Country>
      <Country>Mexico</Country>
    </Countries>
    

    【讨论】:

    • 如果我不使用它,我猜我不需要 Microsoft 命名空间。
    • 我可能应该添加这将包括&lt;Country /&gt; 元素的任何子节点(如果它们存在)。
    【解决方案3】:

    这里有两种不同的解决方案:一种是简单的,另一种是更复杂的,只产生独特的国家/地区:

    .1。获取所有Country 元素:

    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
    
     <xsl:template match="*[not(self::Country)]">
      <xsl:apply-templates select="*"/>
     </xsl:template>
    </xsl:stylesheet>
    

    当对提供的 XML 文档应用此转换时,会产生所需的正确结果

    <Country>Germany</Country>
    <Country>Mexico</Country>
    

    .2。 查找所有独特的国家/地区

    <xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
        <xsl:key name="kCountryByVal" match="Country" use="."/>
    
     <xsl:template match="/">
         <xsl:copy-of select=
           "/*/*/Country[generate-id()
                        =
                         generate-id(key('kCountryByVal',.)[1])
                        ]
           "/>
     </xsl:template>
    </xsl:stylesheet>
    

    当此转换应用于任何具有所提供文档结构的 XML 文档时,其中一些 Country 元素可能具有相同的值,对于每个不同的值,只会生成一个 Country 元素 .

    使用提供的 XML 文档,我们仍然得到相同的结果:

    <Country>Germany</Country>
    <Country>Mexico</Country>
    

    【讨论】:

      【解决方案4】:

      它非常简单,您只需要在 xslt 模板中编写 xml 而不是 html。

      以下(未经测试)应该可以帮助您入门:

      <xsl:template match="/">
        <Countries>
          <xsl:apply-templates select="Customers/Customer" />
        </Countries>
      </xsl:template>
      
      <xsl:template match="Customer">
        <Country>
          <xsl:value-of select="Country" />
        </Country>
      </xsl:template>
      

      另外,对于 XSLT 处理器,我衷心推荐 Visual Studio - 它有一个出色的 XSLT 调试器,可以帮助您无限地理解您的样式表。 (我不确定这个功能是否包含在快速版本中......)

      【讨论】:

        【解决方案5】:

        在拉式样式中,这应该是表达这种转换的较短样式表:

        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:template match="text()"/>
            <xsl:template match="@*|/*|Country|Country/text()">
                <xsl:copy>
                    <xsl:apply-templates select="@* | node()"/>
                </xsl:copy>
            </xsl:template>
        </xsl:stylesheet>
        

        输出:

        <Customers>
            <Country>Germany</Country>
            <Country>Mexico</Country>
        </Customers>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-04-24
          • 2016-08-24
          • 1970-01-01
          • 2017-07-02
          • 1970-01-01
          • 2011-08-29
          • 2022-01-16
          相关资源
          最近更新 更多