我有以下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
想在这里阅读和应用的三种技术。
如果您只需要在显示
item
元素之前有一个空行(如"或将它们分组为..."所建议的那样(,请编写样式表以发出该值。阅读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"/>
我喜欢带有Muenchian分组的Sperberg-McQueens解决方案。我根据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>