有没有办法在 XSLT 转换中用应用模板替换 for-each?
Posted
技术标签:
【中文标题】有没有办法在 XSLT 转换中用应用模板替换 for-each?【英文标题】:Is there a way to replace the for-each with apply-templates in an XSLT Transform? 【发布时间】: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
【问题讨论】:
【参考方案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-templates
或for-each
。
【讨论】:
我得到了想要的输出,然后一些...,valone,valtwo,valthree,valfour 也被输出了,那部分是不正确的。任何想法为什么这样做? @Rod,查看编辑,您当前的方法将处理 partTwo 两次,您需要更正匹配/
的模板中的应用模板。
谢谢,成功了。但是,我认为apply-templates
的select
表达式必须与模板的match
表达式完全匹配?
选择表达式选择的节点必须匹配模板规则中的match
模式。例如select="*"
选择的节点可以匹配match="para"
的模板规则,而select="para"
选择的节点可以匹配match="*"
的规则。
@Rod,我添加了xsl:key
/key
使用的示例。以上是关于有没有办法在 XSLT 转换中用应用模板替换 for-each?的主要内容,如果未能解决你的问题,请参考以下文章
我的多页迭代 PDF 转换器应该使用啥 XSLT:FO 布局?