我有像这样的xml,
<doc>
<section type="Main_Content">
<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="para2">hh</p>
<p id="main">ii</p>
<p id="main">jj</p>
<p id="para1">xx</p>
<p id="main">yy</p>
</section>
<section type="Main_Chapter">
<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 type="Main_Content">
<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>
</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>
</section>
<section type="Main_Chapter">
<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="{@type}">
<xsl:if test="current-group()[1][@id='para1']">
<xsl:attribute name="type" select="'First para'"/>
</xsl:if>
<xsl:if test="current-group()[1][@id='para2']">
<xsl:attribute name="type" select="'Second para'"/>
</xsl:if>
<xsl:apply-templates select="current-group()"/>
</section>
</xsl:for-each-group>
</xsl:template>
从xsl以上获取的结果是,
<doc>
<section type="">
<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>
</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>
</section>
<section type="">
<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>
因此,除了原始type
属性未复制到<section>
节点外,结果外观似乎是正确的。如何修改xsl以将原始type
属性值提供给<section>
个节点?
答案 0 :(得分:4)
问题在于提供的代码的这一部分:
<xsl:template match="section">
<xsl:for-each-group select="p" group-starting-with="p[starts-with(@id, 'para')]">
<section type="{@type}">
请注意,context(current)项是p
元素,并且提供的源XML文档中没有这些元素具有type
属性。
在此您需要type
元素的父级的p
属性。
<强>解决方案强>:
替换:
<section type="{@type}">
使用:
<section type="{../@type}">
现在整个转型变为:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<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="{../@type}">
<xsl:if test="current-group()[1][@id='para1']">
<xsl:attribute name="type" select="'First para'"/>
</xsl:if>
<xsl:if test="current-group()[1][@id='para2']">
<xsl:attribute name="type" select="'Second para'"/>
</xsl:if>
<xsl:apply-templates select="current-group()"/>
</section>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
并应用于提供的源XML文档:
<doc>
<section type="Main_Content">
<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="para2">hh</p>
<p id="main">ii</p>
<p id="main">jj</p>
<p id="para1">xx</p>
<p id="main">yy</p>
</section>
<section type="Main_Chapter">
<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>
产生了想要的正确结果:
<doc>
<section type="Main_Content">
<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>
</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>
</section>
<section type="Main_Chapter">
<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>