我有一个样本“:
<Root>
<A rename="yes,it is option 1"/>
<C rename="no"/>
<A rename="yes,it is option 2"/>
<C rename="no"/>
<C rename="yes"/>
<C rename="no"/>
<A rename="yes,it is option 3"/>
<A rename="yes,it is option 4"/>
<C rename="no"/>
<C rename="yes"/>
<C rename="no"/>
<C rename="no"/>
</Root>
然后我应用这样的模板:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="A">
<p><b>option1: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 1')]])"/></b></p>
<p><b>option2: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 2')]])"/></b></p>
<p><b>option3: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 3')]])"/></b></p>
<p><b>option4: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 4')]])"/></b></p>
</xsl:template>
</xsl:stylesheet>
但我希望输出看起来像这样,如果A之后没有兄弟,我们只是忽略这个。只是打印这些@rename包含“选项”并且还包含元素
option1: 1
option2: 3
option4: 4
我现在得到的是:
option1: 1
option2: 3
option3: 0
option4: 4
option1: 0
option2: 3
option3: 0
option4: 4
option1: 0
option2: 0
option3: 0
option4: 4
option1: 0
option2: 0
option3: 0
option4: 4
答案 0 :(得分:1)
您正在计算最近 A 元素后面的所有 C 元素。这可以通过密钥来完成,将所有此类 C 元素与关联的 A 元素分组
<xsl:key name="lookup" match="C" use="generate-id(preceding-sibling::A[1])" />
要查找至少有一个 C 存在的 A 元素,请执行以下操作:
<xsl:apply-templates select="A[key('lookup', generate-id())]" />
然后要计算选项的数量,你可以只计算键中的元素数量,如下所示:
<xsl:value-of select="count(key('lookup', generate-id()))" />
尝试以下XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:key name="lookup" match="C" use="generate-id(preceding-sibling::A[1])" />
<xsl:template match="/Root">
<xsl:apply-templates select="A[key('lookup', generate-id())]" />
</xsl:template>
<xsl:template match="A">
<xsl:value-of select="concat(@rename, ': ', count(key('lookup', generate-id())) , ' ')" />
</xsl:template>
</xsl:stylesheet>
当这个应用于您的XML示例时,输出以下内容:
yes,it is option 1: 1
yes,it is option 2: 3
yes,it is option 4: 4
请注意,如果你想要'option1'而不是'是,那就是选项1',你可以concat('option', substring-after(@rename, 'option '))
而不仅仅是@rename
请注意,如果重新构建XML,则可以简化此问题。这样的事情会好得多:
<Root>
<A rename="yes,it is option 1">
<C rename="no"/>
</A>
<A rename="yes,it is option 2">
<C rename="no"/>
<C rename="yes"/>
<C rename="no"/>
</A>
<A rename="yes,it is option 3"/>
<A rename="yes,it is option 4">
<C rename="no"/>
<C rename="yes"/>
<C rename="no"/>
<C rename="no"/>
</A>
</Root>
答案 1 :(得分:0)
在XSLT 2.0中,使用xsl:for-each-group
指令会变成一个简单的分组问题。
<xsl:template match="Root">
<xsl:for-each-group group-starting-with="A" select="*">
<xsl:if test="count(current-group()) != 1">
<p>Option <xsl:value-of select="substring-after(current-group()[1]/@rename, 'option ')"/> = <xsl:value-of select="count(current-group())-1"/></p> </xsl:if>
</xsl:for-each-group>
</xsl:template>