XSLT - 将原始属性获取到结果树
XSLT - get original attributes to the result tree
我有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>
SO,除了原始 type
属性未复制到 <section>
节点外,结果似乎是正确的。如何修改 xsl 以将原始 type
属性值获取到 <section>
节点?
问题出在提供的这部分代码中:
<xsl:template match="section">
<xsl:for-each-group select="p" group-starting-with="p[starts-with(@id, 'para')]">
<section type="{@type}">
请注意上下文(当前)项是一个 p
元素,并且在提供的源 XML 文档中 none 这些元素具有 type
属性。
这里你想要 p
元素的父元素的 type
属性.
解决方法:
替换:
<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>
我有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>
SO,除了原始 type
属性未复制到 <section>
节点外,结果似乎是正确的。如何修改 xsl 以将原始 type
属性值获取到 <section>
节点?
问题出在提供的这部分代码中:
<xsl:template match="section">
<xsl:for-each-group select="p" group-starting-with="p[starts-with(@id, 'para')]">
<section type="{@type}">
请注意上下文(当前)项是一个 p
元素,并且在提供的源 XML 文档中 none 这些元素具有 type
属性。
这里你想要 p
元素的父元素的 type
属性.
解决方法:
替换:
<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>