XSLT匹配的模板

时间:2013-03-07 19:10:59

标签: xslt

我有一种情况,我试图通过以下方式匹配模板的许多可能路径:

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

2 个答案:

答案 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>