2013-03-07 131 views
2

我在那里我想了一些可能的路径相匹配,以下列方式模板的情况: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'等),但我只知道其中的2个,'bar'和'bam'。我不想处理这些,但我做的其他人。不幸的是,current()方法没有返回匹配的路径,所以测试总是成功的(即使当路径是'foo/bar/baz'或者'foo/bam/baz'时

我怎么能检索在if-test中匹配的路径?

请注意:我不能有其他特别匹配'foo/bar/baz'和'foo/bam/baz'的xsl:template元素,因为它们在其他地方正在处理(在其他方面)。

回答

2

current函数不返回的路径,它将返回当前上下文节点(即外[]断言它是完全一样的.的,断言它的内该值为.会在它之外)。

而不是使用<xsl:if>你应该定义无操作模板相同someMode匹配你做特定元素不想要的,那么主*模板将仅针对那些你希望。

<xsl:template match="foo/bar/baz | foo/bam/baz" mode="someMode" /> 

<xsl:template match="*" mode="someMode"> 
    <!-- Process here --> 
</xsl:template> 

你说

请注意:我不能有其他的xsl:模板元素专门匹配“富/酒吧/巴兹”和“富/ BAM /巴兹”,因为他们正在其他地方进行处理(以其他方式)。

但是这是模式的整点 - 现有的其他模式foo/bar/baz模板仍然会做同样的,因为他们习惯了。

+0

真棒!非常感谢,修正了它:)不知道你可以在多个模板上使用相同的模式 – starman1979 2013-03-07 19:20:56

+0

@mohisham如果你想到这一点,那就是你一直在做的事 - 通常的元素没有一个'mode'都处于相同的模式(默认模式,没有名字)。 – 2013-03-07 19:27:34

0

如果您有其他与foo/bar/baz和foo/bam/baz匹配的mode =“someMode”模板,那么您在该模式下匹配*的模板将永远不会触发这些元素,并且您的测试即使你重新制定它来说出你想要的东西,有条件的东西永远也是如此。

如果你不完全确定一个与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>