【问题标题】:Is there a way to replace the for-each with apply-templates in an XSLT Transform?有没有办法在 XSLT 转换中用应用模板替换 for-each?
【发布时间】:2018-02-23 15:05:32
【问题描述】:

环境: XSLT 1.0
转换将获取partOne 部分中的每个元素,并使用partTwo 属性在partTwo 部分中查找@field 属性,然后输出@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

【问题讨论】:

    标签: xslt xslt-1.0


    【解决方案1】:

    嗯,改变似乎很简单

    <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-templatesfor-each

    【讨论】:

    • 我得到了想要的输出,然后一些...,valone,valtwo,valthree,valfour 也被输出了,那部分是不正确的。任何想法为什么这样做?
    • @Rod,查看编辑,您当前的方法将处理 partTwo 两次,您需要更正匹配 / 的模板中的应用模板。
    • 谢谢,成功了。但是,我认为apply-templatesselect 表达式必须与模板的match 表达式完全匹配?
    • 选择表达式选择的节点必须匹配模板规则中的match 模式。例如select="*"选择的节点可以匹配match="para"的模板规则,而select="para"选择的节点可以匹配match="*"的规则。
    • @Rod,我添加了xsl:key/key 使用的示例。
    猜你喜欢
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2018-09-23
    • 2020-02-17
    相关资源
    最近更新 更多