我想进行一个转换,该转换能够根据属性(outline-level
)的值嵌套一组同级元素。
这是输入的 xml 文件:
<text>
<para style="Heading 1" outline-level="1">Level 1</para>
<para xml:lang="en" style="Directive">Concept: 1</para>
<para xml:lang="en" style="Heading 2" outline-level="2">Level 2</para>
<para xml:lang="en" style="Directive">Concept: 2</para>
<para xml:lang="en" style="Heading 2" outline-level="2">Level 2</para>
<para xml:lang="en" style="Directive">Concept: 3</para>
<para xml:lang="en" style="Heading 3" outline-level="3">Level 3</para>
<para xml:lang="en" style="Directive">Concept: 4</para>
<para xml:lang="en" style="Heading 3" outline-level="3">Level 3</para>
<para xml:lang="en" style="Directive">Concept: 5</para>
<para xml:lang="en" style="Heading 1" outline-level="1">Level 1</para>
<para xml:lang="en" style="Directive">Concept: 6</para>
<para xml:lang="en" style="Heading 2" outline-level="2">Level 2</para>
<para xml:lang="en" style="Directive">Concept: 7</para>
<para xml:lang="en" style="Heading 3" outline-level="3">Level 3</para>
<para xml:lang="en" style="Directive">Concept: 8</para>
</text>
这就是我想要实现的目标:
<root>
<para id="Concept: 1">Level 1
<para id="Concept: 2">Level 2</para>
<para id="Concept: 3">Level 2
<para id="Concept: 4">Level 3</para>
<para id="Concept: 5">Level 3</para>
</para>
</para>
<para id="Concept: 6">Level1
<para id="Concept: 7">Level 2
<para id="Concept: 8"/>
</para>
</para>
</root>
嵌套级别必须由 @outline-level
的值确定。该数字越大,嵌套的元素就越深。
任何想法将不胜感激。
试试这样吗?
XSLT 1.0
<xsl:stylesheet version="1.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="*"/>
<xsl:key name="child-paras" match="para" use="generate-id(preceding-sibling::para[@outline-level = current()/@outline-level - 1][1])" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/text">
<root>
<xsl:apply-templates select="para[@outline-level=1]"/>
</root>
</xsl:template>
<xsl:template match="para">
<para id="{following-sibling::para[1]}">
<xsl:value-of select="." />
<xsl:apply-templates select="key('child-paras', generate-id())"/>
</para>
</xsl:template>
</xsl:stylesheet>
当应用于示例输入时,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<para id="Concept: 1">Level 1<para id="Concept: 2">Level 2</para>
<para id="Concept: 3">Level 2<para id="Concept: 4">Level 3</para>
<para id="Concept: 5">Level 3</para>
</para>
</para>
<para id="Concept: 6">Level 1<para id="Concept: 7">Level 2<para id="Concept: 8">Level 3</para>
</para>
</para>
</root>
其中(除了缩进的差异)与您的预期输出相同 - 除了id="Concept: 8"
包含文本节点的最后一para
"Level 3"
- 我认为这是正确的。