我有一个像这样的样本xsl,
<doc>
<p type="para">aaxx</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">aaxx</p>
<s>jksjdl</s>
<p type="para">bbcc</p>
<p type="paraX">kkll</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<k>text</k>
<p type="para">bbcc</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<t>text</t>
<p type="paraX">aa</p>
<p type="paraX">kddkll</p>
</doc>
我的要求是,
搜索任何<p type="para">
,然后搜索p
的任意组合,其类型以paraX
和<context type="para”>
开头,并将该内容插入<section>
。
所以,我的预期输出应该是,
<doc>
<section>
<p type="para">aaxx</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">aaxx</p>
</section>
<s>jksjdl</s>
<section>
<p type="para">bbcc</p>
<p type="paraX">kkll</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
</section>
<k>text</k>
<section>
<p type="para">bbcc</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
</section>
<t>text</t>
<p type="paraX">aa</p>
<p type="paraX">kddkll</p>
</doc>
我是在XSLT之后编写的,
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p[@type='para']"/>
<xsl:template match="p[@type='paraX']"/>
<xsl:template match="p[@type='para']">
<section>
<p type="para">
<xsl:apply-templates/>
</p>
<xsl:apply-templates select="following-sibling::*[1]" mode="box"/>
</section>
</xsl:template>
<xsl:template match="p" mode="box">
<p type="{@type}">
<xsl:apply-templates/>
</p>
<xsl:apply-templates select="following-sibling::p[1][@type='paraX'] | following-sibling::context[1][@type='para']" mode="box"/>
</xsl:template>
<xsl:template match="context" mode="box">
<context type="{@type}">
<xsl:apply-templates/>
</context>
<xsl:apply-templates select="following-sibling::p[1][@type='paraX'] | following-sibling::context[1][@type='para']" mode="box"/>
</xsl:template>
但它提供了以下输出,
<doc>
<section>
<p type="para">aaxx</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<context type="para">aaxx</context>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
</section>
<context type="para">aaxx</context>
<s>jksjdl</s>
<section>
<p type="para">bbcc</p>
<p type="paraX">kkll</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
</section>
<k>text</k>
<section>
<p type="para">bbcc</p>
<p type="paraX">aaxx</p>
<p type="paraX">aaxx</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
<p type="paraX">kkll</p>
<context type="para">aaxx</context>
<p type="paraX">kkll</p>
</section>
<context type="para">aaxx</context>
</doc>
知道如何修改模板以获得正确的输出?
答案 0 :(得分:2)
您尚未明确指定要求以确保正确获取代码,但对于提供的输入,以下内容可行:
<xsl:template match="doc">
<doc>
<xsl:for-each-group select="*"
group-starting-with="p[@type='para'] | *[not(self::p | self::context)]">
<xsl:choose>
<xsl:when test="self::p">
<section><xsl:copy-of select="current-group()"/></section>
<xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</doc>
</xsl:template>
我确定您使用兄弟递归的方法可以起作用,但我个人认为,对于每个组的位置分组更清晰,更容易调试。