XSLT - 将现有节点放在不同的位置
XSLT - place existing nodes in different position
我有 xml 如下,
<doc>
<section>
<p note="edit"></p>
<p note="foot"></p>
<p note="front"></p>
<c>content</c>
</section>
<section>
.......
</section>
</doc>
我需要的是摆脱 <p>
具有属性 edit 或 foot 的节点,并将它们添加到 <section>
节点的末尾。
所以输出应该是
<doc>
<section>
<p note="front"></p>
<c>content</c>
</section>
<p note="edit"></p>
<p note="foot"></p>
<section>
.......
</section>
</doc>
我可以通过简单地使用如下所示的空模板来删除这些节点,
<xsl:template match="p[@note='edit']"/>
<xsl:template match="p[@note='foot']"/>
但是我无法使用任何方法将那些删除的节点放置在 <section>
节点的末尾。
有什么建议吗?
提前致谢
在您的 XSLT 中某处有 元素的输出,您在内部使用 (和脚)作为空模板以避免插入这些(我猜测)。
在 元素之后,您可以使用元素
<xsl:template match="/doc/section/p[@note='edit']|/doc/section/p[@note='foot']">
<xsl:copy-of select="."/>
</xsl:template>
用于在此处插入这些内容。
你可以这样试试:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
<xsl:copy-of select="p[@note='edit' or @note='foot']"/>
</xsl:template>
<xsl:template match="p[@note='edit' or @note='foot']"/>
</xsl:stylesheet>
简要说明:
<xsl:template match="node()|@*">...
:标识模板。我假设您对此很熟悉。
<xsl:template match="section">...
: 复制 '<p>
属性为 edit 或 foot' 的节点到当前 <section>
, 居住.
<xsl:template match="p[@note='edit' or @note='foot']"/>
: 用于从原始位置删除具有属性 edit 或 foot' 的 '<p>
节点的空模板。
对于这种情况,我建议在与该部分匹配的模板中使用 xsl:choose。
此模板创建部分元素并对节点重新排序。
<xsl:template match="section">
<xsl:choose>
<xsl:when test="p[@note= 'front']">
<section>
<xsl:apply-templates select="p[@note= 'front'] | c"/>
</section>
<xsl:apply-templates select="p[@note != 'front']"/>
</xsl:when>
<xsl:otherwise>
<section>
<xsl:apply-templates/>
</section>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
或者简单地说:
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"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:variable name="footnotes" select="p[@note='edit' or @note='foot']" />
<xsl:copy>
<xsl:apply-templates select="@*|node() except $footnotes"/>
</xsl:copy>
<xsl:apply-templates select="$footnotes"/>
</xsl:template>
</xsl:stylesheet>
我有 xml 如下,
<doc>
<section>
<p note="edit"></p>
<p note="foot"></p>
<p note="front"></p>
<c>content</c>
</section>
<section>
.......
</section>
</doc>
我需要的是摆脱 <p>
具有属性 edit 或 foot 的节点,并将它们添加到 <section>
节点的末尾。
所以输出应该是
<doc>
<section>
<p note="front"></p>
<c>content</c>
</section>
<p note="edit"></p>
<p note="foot"></p>
<section>
.......
</section>
</doc>
我可以通过简单地使用如下所示的空模板来删除这些节点,
<xsl:template match="p[@note='edit']"/>
<xsl:template match="p[@note='foot']"/>
但是我无法使用任何方法将那些删除的节点放置在 <section>
节点的末尾。
有什么建议吗?
提前致谢
在您的 XSLT 中某处有
在
<xsl:template match="/doc/section/p[@note='edit']|/doc/section/p[@note='foot']">
<xsl:copy-of select="."/>
</xsl:template>
用于在此处插入这些内容。
你可以这样试试:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
<xsl:copy-of select="p[@note='edit' or @note='foot']"/>
</xsl:template>
<xsl:template match="p[@note='edit' or @note='foot']"/>
</xsl:stylesheet>
简要说明:
<xsl:template match="node()|@*">...
:标识模板。我假设您对此很熟悉。<xsl:template match="section">...
: 复制 '<p>
属性为 edit 或 foot' 的节点到当前<section>
, 居住.<xsl:template match="p[@note='edit' or @note='foot']"/>
: 用于从原始位置删除具有属性 edit 或 foot' 的 '<p>
节点的空模板。
对于这种情况,我建议在与该部分匹配的模板中使用 xsl:choose。 此模板创建部分元素并对节点重新排序。
<xsl:template match="section">
<xsl:choose>
<xsl:when test="p[@note= 'front']">
<section>
<xsl:apply-templates select="p[@note= 'front'] | c"/>
</section>
<xsl:apply-templates select="p[@note != 'front']"/>
</xsl:when>
<xsl:otherwise>
<section>
<xsl:apply-templates/>
</section>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
或者简单地说:
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"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:variable name="footnotes" select="p[@note='edit' or @note='foot']" />
<xsl:copy>
<xsl:apply-templates select="@*|node() except $footnotes"/>
</xsl:copy>
<xsl:apply-templates select="$footnotes"/>
</xsl:template>
</xsl:stylesheet>