我有这样的XML:
<state>
<current>block</current>
<next>air</next>
</state>
<state>
<current>air</current>
<next>block</next>
</state>
<state>
<current>air</current>
<next>swim</next>
</state>
<state>
<current>block</current>
<next>air</next>
</state>
所以我想将所有&#34;当前&#34; +&#34; next&#34;我可以遇到的每个当前和下一个不同的元素(使用XSLT 1.0)
air
block
swim
我已经使用了muenchina方法来分组&#34;当前&#34;元素或&#34;下一个&#34;元素,但不是两个在同一时间。
我该怎么办?
答案 0 :(得分:1)
好吧,事实上它比我预期的要简单。
我只是简单地说:
<xsl:key name="groups" match="//current|//next" use="." />
然后将其用于:
<xsl:template match="current|next" mode="node" >
<xsl:if test="generate-id() = generate-id(key('groups', normalize-space(.)))">
<xsl:value-of select="."/>
</xsl:if>
</xsl:template>
答案 1 :(得分:0)
只需应用已排序的查询并输出唯一的查询:
<xsl:variable name="states">
<xsl:value-of select="//state/*[contains(name(), 'current next')]/text()"/>
</xsl:variable>
<xsl:for-each select="str:tokenize($states)">
<xsl:sort select="text()"/>
<xsl:if test="preceding-sibling::*/text() != text()">
<xsl:element name="state"><xsl:value-of select="text()"/></xsl:element>
</xsl:if>
</xsl:for-each>
这是一个更新,其中包含一个使用exsl node-set的示例,用于不支持tokenize的xslt实现:
<xsl:variable name="states">
<xsl:for-each select="//state/*[contains(name(), 'current next')]">
<xsl:element name="state">
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:variable>
<xsl:for-each select="exsl:node-set($states)/*">
<xsl:sort select="text()"/>
<xsl:if test="preceding-sibling::*/text() != text()">
<xsl:element name="state"><xsl:value-of select="text()"/></xsl:element>
</xsl:if>
</xsl:for-each>
如果XSLT可以跨多个级别对节点集进行排序,也值得一看。我原先预计这不起作用,但现在不太确定,因为我想知道libxsl是否会先破坏节点集。如果没有,则previous-sibling :: reference将失败,因为它只引用immediate节点,而不是选择的节点:
<xsl:for-each select="//state/*[contains(name(), 'current next')]">
<xsl:sort select="text()"/>
<xsl:if test="preceding-sibling::*/text() != text()">
<xsl:element name="state"><xsl:value-of select="text()"/></xsl:element>
</xsl:if>
</xsl:for-each>