我有一种情况,我试图通过以下方式匹配模板的许多可能路径:
<xsl:template match="blah">
<xsl:apply-templates select="foo/*/baz" mode="someMode"/>
</xsl:template>
<xsl:template match="*" mode="someMode">
<xsl:if test="current() != 'foo/bar/baz' and
current() ! ='foo/bam/baz'">
<!-- Process here -->
</xsl:if>
</xsl:template>
你可以看到,'foo'下有任意数量的元素都有'baz'元素(例如'bar','bam','bal','bav'等)但我只知道其中的两个,'酒吧'和'bam'。我不想处理这些,而是我做的其他人。不幸的是,current()方法没有返回匹配的路径,所以测试总是成功(即使路径是'foo / bar / baz'或'foo / bam / baz'。
如何检索if-test中匹配的路径?
请注意:我不能拥有专门匹配'foo / bar / baz'和'foo / bam / baz'的其他xsl:template元素,因为它们正在其他地方处理(以其他方式)。< / p>
答案 0 :(得分:2)
current
函数不返回路径,它返回当前上下文节点(即在[]
谓词之外它与.
完全相同,在谓词中它是.
将在其之外的值。
不应使用<xsl:if>
,而应为与不所需的特定元素相匹配的相同someMode
定义无操作模板,然后是主{{1}只有那些你做想要的人才会触发模板。
*
你说那个
请注意:我不能拥有专门匹配'foo / bar / baz'和'foo / bam / baz'的其他xsl:template元素,因为它们正在其他地方处理(以其他方式)。< / p>
但这是模式的全部要点 - 其他模式的现有<xsl:template match="foo/bar/baz | foo/bam/baz" mode="someMode" />
<xsl:template match="*" mode="someMode">
<!-- Process here -->
</xsl:template>
模板仍然会像以前一样。
答案 1 :(得分:0)
如果你有其他模板的模式=“someMode”匹配foo / bar / baz和foo / bam / baz,那么你在这种模式下匹配*的模板永远不会触发这些元素,并且你的条件中的测试即使你重新制定它以说出你想要的东西,它也将永远是真实的。
如果您不完全确定与foo / bar / baz或foo / bam / baz模式匹配的给定元素在其他位置匹配,并且您希望确保if
中的代码声明不会为它开火,你可以重铸你的测试
test="not(self::baz/parent::bar/parent::foo
or self::baz/parent::bam/parent::foo)"
许多XSLT程序员会以不同的方式编写它,不过通过在模板的匹配模式的谓词中添加该测试:
<xsl:template mode="someMode"
match="*[not(self::baz/parent::bar/parent::foo
or self::baz/parent::bam/parent::foo)]">
<!-- process ... -->
</xsl:template>