我有以下xml(为此目的简化)
<content>
<p1>blabla</p1>
<p2>blabla</p2>
<p2>blabla</p2>
<p1>blabla</p1>
<p3>blabla</p3>
<p1>blabla</p1>
<p2>blabla</p2>
<p2>blabla</p2>
<p1>blabla</p1>
<p3>blabla</p3>
<p2>blabla</p2>
</content>
我想将所有p1元素和p2元素分组,但后者只有在前一个兄弟是p1元素的情况下。
我使用了以下xslt:
<xsl:for-each-group select="*" group-adjacent="self::p1 or (self::p2 and preceding-sibling::p1[1])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<ol_coll>
<xsl:apply-templates select="current-group()"/>
</ol_coll>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
但我在语法中忽略了一些东西,因为它没有看到前一个元素,而是整个树。所以我得到以下回复
<content>
<ol_coll>
<p1>blabla</p1>
<p2>blabla</p2>
<p2>blabla</p2>
<p1>blabla</p1>
</ol_coll>
<p3>blabla</p3>
<ol_coll>
<p1>blabla</p1>
<p2>blabla</p2>
<p2>blabla</p2>
<p1>blabla</p1>
</ol_coll>
<p3>blabla</p3>
<ol_coll>
<p2>blabla</p2>
</ol_coll>
</content>
但我希望的是以下内容:
<content>
<ol_coll>
<p1>blabla</p1>
<p2>blabla</p2>
</ol_coll>
<p2>blabla</p2>
<p1>blabla</p1>
<p3>blabla</p3>
<ol_coll>
<p1>blabla</p1>
<p2>blabla</p2>
</ol_coll>
<p2>blabla</p2>
<p1>blabla</p1>
<p3>blabla</p3>
<p2>blabla</p2>
</content>
任何能指出我错误的人?谢谢!
答案 0 :(得分:2)
我认为您需要将条件更改为preceding-sibling::*[1][self::p1]
,然后您需要确保不包装单个元素。所以用
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="content">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="self::p1 or (self::p2 and preceding-sibling::*[1][self::p1])">
<xsl:choose>
<xsl:when test="current-grouping-key() and current-group()[2]">
<ol_coll>
<xsl:apply-templates select="current-group()"/>
</ol_coll>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我得到你发布的结果(运行Saxon 9.4)。