使用XSL递归循环遍历XML

时间:2017-03-14 13:53:35

标签: xml templates xslt recursion xslt-1.0

我想使用XSL将以下XML文件转换为HTML页面:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Recursion.xsl"?>
<CompareResults hasChanges="true">
    <CompareItem name="Appel"  status="Identical">
        <Properties>
            <Property name="Abstract" model="false" baseline="false" status="Identical"/>
        </Properties>

        <CompareItem name="Banaan"  status="Identical">
            <Properties>
                <Property name="Abstract" model="false" baseline="false" status="Identical"/>
            </Properties>
        </CompareItem>

        <CompareItem name="Kiwi"  status="Identical">

            <CompareItem name="Peer"  status="Model only">
                <Properties>
                    <Property name="Abstract" model="false" baseline="false" status="Identical"/>
                    <Property name="Notes" model="PeerName" status="Model only"/>
                </Properties>
            </CompareItem>

            <Properties>
                <Property name="Abstract" model="false" baseline="false" status="Identical"/>
            </Properties>
        </CompareItem>
    </CompareItem>
</CompareResults>

输出应包含具有@status“仅模型”的元素以及指向此元素的整个路径。
所以,对于这个例子:

  • Appel
  • Kiwi
  • Peer
  • 注释

我的想法是我应该通过循环遍历XML来实现这一点,但问题是我无法弄清楚模板如何返回值。那么,有人能告诉我是否(以及如何)返回值或如何构造XSL以符合所需的输出?

这是我当前的XSL文件:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
        <xsl:apply-templates/>
  </body>
  </html>
</xsl:template>

<xsl:template match="/CompareResults">
    <xsl:apply-templates select="CompareItem"/>
</xsl:template>

<!--CompareItem -->
<xsl:template match="CompareItem">

    <xsl:value-of select="@name"/>

    <!-- Sub elements -->   
    <xsl:apply-templates select="CompareItem"/>
</xsl:template>

</xsl:stylesheet>

2 个答案:

答案 0 :(得分:0)

如果我正确猜测(!),你想做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>

<xsl:template match="/CompareResults">
    <html>
        <body>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

<xsl:template match="*[@name and descendant-or-self::*/@status='Model only']">
    <p>
        <xsl:value-of select="@name" />
    </p>
    <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

这将为满足两者的每个元素输出p

  1. 它有name attribute;
  2. 它或其中一个后代的status属性的值为"Model only"
  3. 导致:

    <html>
       <body>
          <p>Appel</p>
          <p>Kiwi</p>
          <p>Peer</p>
          <p>Notes</p>
       </body>
    </html>
    

答案 1 :(得分:0)

获取@name属性的所有元素的@status属性值,其值为&#34;仅限模型&#34;因为ul列表可以在没有递归的情况下完成。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*" />    

  <xsl:template match="/">
    <html>
      <body>
        <ul>
          <xsl:apply-templates select="//*[@status = 'Model only']" mode="xx" />
        </ul>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="*" mode="xx" >
    <li><xsl:value-of select="@name" /></li>
    <xsl:apply-templates />
  </xsl:template>

</xsl:stylesheet>

结果是:

<html>
    <body>
         <ul>
            <li>Peer</li>
            <li>Notes</li>
        </ul>
    </body>
</html>

这在浏览器中效果很好。