XSLT:如何根据级别匹配元素的第一次或第二次出现

时间:2016-09-09 06:25:36

标签: xslt-2.0

我需要在第一个div上匹配类名称row-1,它位于另一个div中,类名为row-1。这很容易。但问题是有时候第一个带有类名为row-1的div是唯一具有该类名的div。当发生这种情况时,我需要匹配它。

xml可能如下所示:场景1

<div class="row-1">
    <div class="someClassName">
        <div class="row-1">content</div> (match this one)
        <div class="row-1">content</div>
        <div class="row-1">content</div>
    </div>
</div>

或者像这样:场景2

<div class="row-1"> (match this one)
    <div class="someClassName">
        <div class="somOtherClassName">content</div>
    </div>
</div>

此标记将在文档的几个深层(意味着将围绕此文档的其他div)。

这是第一个场景中匹配的xsl:

<xsl:template match="//div[contains(concat(' ', @class, ' '), ' row-1 ')]//div[contains(concat(' ', @class, ' '), ' row-1 ')][position() = 1]">  

但是当我需要检查两者时xsl会怎样?一次只能出现一种情况。我尝试使用xsl:choose,但不允许使用模板:匹配内部。

感谢任何建议。

修改
这似乎适用于方案2:

<xsl:template match="//div[contains(concat(' ', @class, ' '), ' row-1 ')][not(descendant::div[contains(concat(' ', @class, ' '), ' row-1 ')])][not(ancestor::div[contains(concat(' ', @class, ' '), ' row-1 ')])]">

然而,这似乎有点冗长。如果有人有更好的方法,请告诉我。

1 个答案:

答案 0 :(得分:0)

如果我正确理解了任务,则需要在文档中匹配第一个div和类“row-1”,该文档不包含任何嵌套级别的“row-1”类的其他div。您可以使用具有后代轴的XPath“is”运算符来选择文档中第一次出现的必要元素:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:t="stackoverflow.com"    
               version="2.0">


    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>


    <xsl:template match="node()">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>


    <xsl:template match="attribute()">
        <xsl:copy/>
    </xsl:template>


    <xsl:template match="div[. is (//div)[t:is-row1-div(.)][empty(descendant::div[t:is-row1-div(.)])][1]]">
        <xsl:copy>
            <xsl:apply-templates select="attribute()"/>
            <xsl:text>(Matched) </xsl:text>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>


    <xsl:function name="t:is-row1-div" as="xs:boolean">
        <xsl:param name="div" as="element(div)"/>

        <xsl:sequence select="boolean($div/@class eq 'row-1')"/>
    </xsl:function>


</xsl:transform>

您可以在此处测试此转换:http://xsltransform.net/ejivdH3