我有以下xml结构:
<?xml version="1.0"?>
<items>
<item/>
<desc/>
<desc2/>
<desc3/>
<price1/>
<info/>
<info/>
<info2/>
<item/>
<desc/>
<price1/>
<price2/>
<price3/>
<info1/>
<anotheriinfo/>
<specialinfo/>
<item/>
<desc/>
<price1/>
</items>
其中<item>
不是以下节点的父级。
我需要将不同的项目与相应的信息和定价分组。有没有办法在下一个<item>
之前选择<item>
和所有后续节点并应用一些logig?或者将它们分组为
<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<desc/>
<desc2/>
<desc3/>
<price1/>
<info/>
<info/>
<info2/>
</item>
<item>
<desc/>
<price1/>
<price2/>
<price3/>
<info1/>
<anotheriinfo/>
<specialinfo/>
</item>
<item>
<desc/>
<price1/>
</item>
</items>
我需要使用XSLT 1.0
答案 0 :(得分:2)
您可能想要阅读并在此处应用的三种技巧。
如果你想要的只是item
元素显示之前的空白行(如#34所示;或者将它们分组为......&#34;),请编写样式表发出那个。
阅读Muenchian分组;要分组的值是名为item
的前一个兄弟的数量(对于名为item
的节点)或者名为item
的前一个兄弟的数量加一(item
元件)。
学习通过首先在其子项上调用模板apply-templates
然后在其右边兄弟上调用来执行树遍历。在这种情况下,基本模式是
<xsl:template match="items">
<xsl:apply-templates match="item"/>
</
<xsl:template match="item">
<xsl:copy>
<!-- handle descendants, if your current items have any ... -->
<xsl:apply-templates match="@*|node()"/>
<!-- bring right siblings into the content ... -->
<xsl:apply-templates match="following-sibling::*[1]"
mode="group-nodes"/>
</
</
<xsl:template match="*" mode="group-nodes" priority="1">
<!-- 1 handle this element -->
<!-- modify next line if items elements can nest ... -->
<xsl:copy-of select="."/>
<!-- 2 handle next sibling -->
<xsl:apply-templates match="following-sibling::*[1]"
mode="group-nodes"/>
</
</
<xsl:template match="item" mode="group-nodes" priority="10"/>
答案 1 :(得分:1)
我喜欢Sperberg-McQueens与Muenchian分组的解决方案。我采用了一种完全不同的方法(再次!!),基于position()
以及产生所需结果的后续兄弟姐妹的数量。只是想分享一下:
<xsl:template match="items">
<xsl:copy>
<!-- total number of items -->
<xsl:variable name="countItems" select="count(item)"/>
<!-- edit: copy elements before first item -->
<xsl:copy-of select="*[following-sibling::item[$countItems]]"/>
<xsl:for-each select="item">
<!-- position of current item -->
<xsl:variable name="position" select="position()"/>
<xsl:choose>
<xsl:when test="following-sibling::item">
<xsl:copy>
<!-- get all elements before next item -->
<!-- = all elements followed by (total items minus current position) items -->
<xsl:apply-templates select="following-sibling::*[following-sibling::item[$countItems - $position]]"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="following-sibling::*"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<!-- identity transform -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>