有没有办法在XSLT转换中用for-templates替换for-each?

时间:2017-09-14 14:56:24

标签: xslt xslt-1.0

环境: XSLT 1.0
转换将使用partOne属性中的@field部分中的每个元素和partTwo部分中的查找@find属性,然后输出@value属性。

我正在使用for-each循环,并想知道apply-templates是否有效?

XML

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="file.xslt"?>

<xml>
  <partOne>
    <target field="hello"/>
    <target field="world"/>
  </partOne>
  <partTwo>
    <number input="2" find="hello" value="valone" />
    <number input="2" find="world" value="valtwo"  />
    <number input="2" find="hello" value="valthree"  />
    <number input="2" find="world" value="valfour"  />    
  </partTwo>
</xml>

XSL

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

  <xsl:output method="text"/>

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

  <xsl:template match="/xml/partOne/target">
    ,<xsl:value-of select="@field"/>

    <xsl:for-each select="/xml/partTwo/number[@find=current()/@field]">
      ,<xsl:value-of select="@value"/>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

输出

,hello
  ,valone
  ,valthree

,world
  ,valtwo
  ,valfour

1 个答案:

答案 0 :(得分:2)

嗯,改变似乎是直截了当的

<xsl:for-each select="/xml/partTwo/number[@find=current()/@field]">
  ,<xsl:value-of select="@value"/>
</xsl:for-each>

<xsl:apply-templates select="/xml/partTwo/number[@find=current()/@field]"/>

带有模板

<xsl:template match="partTwo/number">
      ,<xsl:value-of select="@value"/>
</xsl:template>

到目前为止,您的根模板处理了将其更改为

所需的所有元素
  <xsl:template match="/">
    <xsl:apply-templates select="xml/partOne"/>
  </xsl:template>

避免两次处理partTwo元素。

对于交叉引用,您可能希望在两个版本中都使用密钥:

<xsl:key name="ref" match="partTwo/number" use="@find"/>
对于select="key('ref', @field)"select="/xml/partTwo/number[@find=current()/@field]"

然后apply-templates代替for-each