我有一个xml如下,
<doc>
<section>
<p id="main">aa</p>
<p id="main">bb</p>
<p id="main">cc</p>
<p id="para1">dd</p>
<p id="main">ee</p>
<p id="main">ff</p>
<p id="main">gg</p>
<p id="para2">hh</p>
<p id="main">ii</p>
<p id="main">jj</p>
<p id="para1">xx</p>
<p id="main">yy</p>
<p id="main">zz</p>
</section>
</doc>
我的任务是根据id="para1"
和id='para2'
属性对上述内容进行分组,并为每个组添加一个部分。我想要的输出是
<doc>
<section>
<p id="main">aa</p>
<p id="main">bb</p>
<p id="main">cc</p>
</section>
<section type="First para">
<p id="para1">dd</p>
<p id="main">ee</p>
<p id="main">ff</p>
<p id="main">gg</p>
</section>
<section type="Second para">
<p id="para2">hh</p>
<p id="main">ii</p>
<p id="main">jj</p>
</section>
<section type="First para">
<p id="para1">xx</p>
<p id="main">yy</p>
<p id="main">zz</p>
</section>
</doc>
执行此任务的xsl如下,
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:for-each-group select="p" group-starting-with="p[starts-with(@id, 'para')]">
<section type="?">
<xsl:apply-templates select="current-group()"/>
</section>
</xsl:for-each-group>
</xsl:template>
这个xsl可以完成这项工作,但是你能否建议一种方法,如何根据组添加type
节点的<section>
属性值?
答案 0 :(得分:2)
以下样式表:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:for-each-group select="p" group-starting-with="p[starts-with(@id, 'para')]">
<section>
<xsl:if test="current-group()[1][not(@id='main')]">
<xsl:attribute name="type" select="current-group()[1]/@id"/>
</xsl:if>
<xsl:apply-templates select="current-group()"/>
</section>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
将返回:
<强>结果强>
<?xml version="1.0" encoding="utf-8"?>
<doc>
<section>
<p id="main">aa</p>
<p id="main">bb</p>
<p id="main">cc</p>
</section>
<section type="para1">
<p id="para1">dd</p>
<p id="main">ee</p>
<p id="main">ff</p>
<p id="main">gg</p>
</section>
<section type="para2">
<p id="para2">hh</p>
<p id="main">ii</p>
<p id="main">jj</p>
</section>
<section type="para1">
<p id="para1">xx</p>
<p id="main">yy</p>
<p id="main">zz</p>
</section>
</doc>
将“第1段”和“第2段”分别转换为“第一段”和“第二段”可能更复杂。这将有助于了解可能出现的所有可能组合。如果它始终采用“paraN”格式,那么您可以使用:
<xsl:attribute name="type">
<xsl:number value="substring-after(current-group()[1]/@id, 'para')" format="Ww" ordinal="yes"/>
<xsl:text> para</xsl:text>
</xsl:attribute>
生产:
<?xml version="1.0" encoding="utf-8"?>
<doc>
<section>
<p id="main">aa</p>
<p id="main">bb</p>
<p id="main">cc</p>
</section>
<section type="First para">
<p id="para1">dd</p>
<p id="main">ee</p>
<p id="main">ff</p>
<p id="main">gg</p>
</section>
<section type="Second para">
<p id="para2">hh</p>
<p id="main">ii</p>
<p id="main">jj</p>
</section>
<section type="First para">
<p id="para1">xx</p>
<p id="main">yy</p>
<p id="main">zz</p>
</section>
</doc>