我有这个xml文件:
<A>
<B>
<elt>Add</elt>
...there are some element here
<bId>2</bId>
</B>
<B>
<elt>Add</elt>
...there are some element here
<bId>2</bId>
</B>
<B>
<elt>Add</elt>
...there are some element here
<bId>2</bId>
</B>
<B>
<elt>can</elt>
...there are some element here
<bId>3</bId>
</B>
<B>
<elt>can</elt>
...there are some element here
<bId>3</bId>
</B>
我想检查每个 bId 元素的值。如果此值与前面或后面的 bId 元素相同,那么我将把bloc B 的其他元素放在另一个集合中,除了元素 bId < / strong>将在转换后被拒绝。为了让您的问题得到理解,这是预期的输出:
<CA>
<cplx>
<spRule>
<elt>Add</elt>
...
</spRule>
<spRule>
<elt>Add</elt>
...
</spRule>
<spRule>
<elt>Add</elt>
...
</spRule>
</cplx>
<cplx>
<spRule>
<elt>can</elt>
...
</spRule>
<spRule>
<elt>can</elt>
...
</spRule>
</cplx>
</CA>
即使xml文件中的元素没有按 bId 的值排序,我也希望获得相同的预期输出。 我尝试使用这个xsl代码:
<xsl:for-each select="bId"
<CA>
<cplx>
<xsl:choose>
<xsl:when test="node()[preceding::bId]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:when>
</cplx>
</CA>
</xsl:for-each>
但它没有走路。有人可以帮帮我吗? 感谢
答案 0 :(得分:2)
假设你想要的第一个描述是将具有相同bId
值的相邻元素分组,那么XSLT 1.0的方法如下:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:key name="k1"
match="B[bId = preceding-sibling::B[1]/bId]"
use="generate-id(preceding-sibling::B[not(bId = preceding-sibling::B[1]/bId)][1])"/>
<xsl:template match="A">
<CA>
<xsl:apply-templates select="B[not(preceding-sibling::B[1]) or not(bId = preceding-sibling::B[1]/bId)]"/>
</CA>
</xsl:template>
<xsl:template match="B">
<cplx>
<xsl:apply-templates select=". | key('k1', generate-id())" mode="sp"/>
</cplx>
</xsl:template>
<xsl:template match="B" mode="sp">
<spRule>
<xsl:copy-of select="node()[not(self::bId)]"/>
</spRule>
</xsl:template>
</xsl:stylesheet>
如果您只想将具有相同B
值的所有bId
元素分组,请使用
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:key name="k1"
match="B"
use="bId"/>
<xsl:template match="A">
<CA>
<xsl:apply-templates select="B[generate-id() = generate-id(key('k1', bId)[1])]"/>
</CA>
</xsl:template>
<xsl:template match="B">
<cplx>
<xsl:apply-templates select="key('k1', bId)" mode="sp"/>
</cplx>
</xsl:template>
<xsl:template match="B" mode="sp">
<spRule>
<xsl:copy-of select="node()[not(self::bId)]"/>
</spRule>
</xsl:template>
</xsl:stylesheet>