首页 > 解决方案 > XSLT 属性的提取和转换

问题描述

给定以下 XML:

<document id="1" class="a">
  <level1 id="2">Hello
    <level2 id="3" class="b">World</level2>
  </level1>     
  <level1 id="4" class="c">foo
     <level2 id="5">
         <level3 id="6" class="d">bar</level3>
     </level2>
  </level1>

</document>

如何编写输出以下内容的样式表?:

<listOfItemsWithClass>
  <item>
    <id>1</id>
    <class>a</class>
  </item>
 
  <item>
    <id>3</id>
    <class>b</class>
  </item>
  <item>
    <id>4</id>
    <class>c</class>
  </item>
  <item>
    <id>6</id>
    <class>d</class>
  </item>
</listOfItemsWithClass>

实际上,对于源文档层次结构中任何级别的每个 xml 元素,如果类属性具有任何值,则在父级<item>内的转换中创建并输出一个元素<listOfItemsWithClass>

标签: xmlxslt

解决方案


要遍历所有节点,您可以使用<xsl:for-each select="//*">. 星号执行通配符匹配。or您可以使用语法建立一个元素列表|。例如:<xsl:for-each select="//document | //level1 | //level2| //level3">

过滤掉属性中不包含值的节点class。利用[@class!='']

例如:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <listOfItemsWithClass>
            <xsl:for-each select="//*[@class!='']">
                <item>
                    <id>
                        <xsl:value-of select="@id"/>
                    </id>
                    <class>
                        <xsl:value-of select="@class"/>
                    </class>
                </item>
            </xsl:for-each>
        </listOfItemsWithClass>
    </xsl:template>
</xsl:stylesheet>

推荐阅读