这是一个后续问题“选择当前元素和当前元素的下一个元素之间的所有元素” https://stackoverflow.com/q/16145859/2115381。即使我不确定创建一个新问题是否是正确的方法,但我还是这样做。因为原来的问题已经回答了,但是后来又改变了。所以在我看来,改变的问题是开放的。另外,我认为更改后的问题应该放回统计数据中,如果它适合答案。
问题是如何从“平面”xml(如书籍描述)创建分层 xml。
输入的xml是这样的
<root>
<heading_1>Section 1</heading_1>
<para>...</para>
<list_1>...</list_1>
<heading_2>Section 1.1</heading_2>
<para>...</para>
<heading_3>Section 1.1.1</heading_3>
<para>...</para>
<list_1>...</list_1>
<heading_2>Section 1.2</heading_2>
<para>...</para>
<footnote>...</footnote>
<heading_1>Section 2</heading_1>
<para>...</para>
<list_1>...</list_1>
<heading_2>Section 2.1</heading_2>
<para>...</para>
<list_1>...</list_1>
<list_2>...</list_2>
<heading_3>Seciton 2.1.1</heading_3>
<para>...</para>
<heading_2>Section 2.2</heading_2>
<para>...</para>
<footnote>...</footnote>
</root>
Each <heading_*>
应该被解释为一个开始<section>
预期的输出 xml 是。
<section>
<title>Section 1</title>
<para>...</para>
<list_1>...</list_1>
<section>
<title>Section 1.1</title>
<para>...</para>
<section>
<title>Section 1.1.1</title>
<para>...</para>
<list_1>...</list_1>
</section>
</section>
<section>
<title>Section 1.2</title>
<para>...</para>
<footnote>...</footnote>
</section>
</section>
<section>
<title>Section 2</title>
<para>...</para>
<list_1>...</list_1>
<section>
<title>Section 2.1</title>
<para>...</para>
<list_1>...</list_1>
<list_2>...</list_2>
<section>
<title>Section 2.1.1</title>
<para>...</para>
</section>
</section>
<section>
<title>Section 2.2</title>
<para>...</para>
<footnote>...</footnote>
</section>
</section>
我也尝试了一段时间,根据原始解决方案找到了解决方案@JLRishe https://stackoverflow.com/a/16146259/2115381。所以我找到了一个,并喜欢将其放在这里作为一种可能性的答案。我希望有一个更容易理解的解决方案。
这是适用于任何航向深度的通用解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kChildHeader"
match="/*/*[starts-with(local-name(), 'heading_')]"
use="generate-id(preceding-sibling::*
[local-name() =
concat('heading_',
substring-after(local-name(current()), '_') - 1
)][1]
)"/>
<xsl:key name="kChildItem"
match="/*/*[not(starts-with(local-name(), 'heading_'))]"
use="generate-id(preceding-sibling::*
[starts-with(local-name(), 'heading_')][1])"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="heading_1" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(local-name(), 'heading_')]">
<xsl:copy>
<xsl:apply-templates select="key('kChildHeader', generate-id()) |
key('kChildItem', generate-id())"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当在示例输入上运行时,会产生:
<root>
<heading_1>
<para>...</para>
<list_1>...</list_1>
<heading_2>
<para>...</para>
<heading_3>
<para>...</para>
<list_1>...</list_1>
</heading_3>
</heading_2>
<heading_2>
<para>...</para>
<footnote>...</footnote>
</heading_2>
</heading_1>
<heading_1>
<para>...</para>
<list_1>...</list_1>
<heading_2>
<para>...</para>
<list_1>...</list_1>
<list_2>...</list_2>
<heading_3>
<para>...</para>
</heading_3>
</heading_2>
<heading_2>
<para>...</para>
<footnote>...</footnote>
</heading_2>
</heading_1>
</root>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)