XSLT 通过 splitter-element 拆分元素 [英] XSLT split elements by splitter-element
问题描述
我已尝试将此处提出的类似问题的解决方案结合起来,但所有这些解决方案都适用于非常具体的情况.我的情况如下:我有一个包含一些标签的任意 xml 文档,比如说
.我想要的是像这样拆分这些标签的父元素:
I've tried to combine solutions to the similar questions asked here but all of them work in very specific cases. My case is the following: I have an arbitrary xml document which contains some tags, let's say <separator/>
. What I want is to split parent elements of these tags like that:
输入:
<some_tag some_attr="some_value">
some text
<some_other_tag>some another text</some_other_tag>
<separator/>
some other content
</some_tag>
输出:
<some_tag some_attr="some_value">
some text
<some_other_tag>some another text</some_other_tag>
</some_tag>
<separator/>
<some_tag some_attr="some_value">
some other content
</some_tag>
另外,我仅限于 XSLT 1.0,因为项目中使用了 Xalan
Also, I am limited to XSLT 1.0 since Xalan is used in the project
推荐答案
要么使用兄弟递归,要么使用键来查找属于"分隔符的节点.复制最后一个分隔符之后的内容需要额外小心:
Either use sibling recursion or use a key to find the nodes "belonging" to a separator. Additional care is needed to copy stuff following the last separator:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="sep" match="*[separator]/node()[not(self::separator)]" use="generate-id(following-sibling::separator[1])"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[separator]">
<xsl:apply-templates select="separator" mode="split"/>
<xsl:if test="separator[last()]/following-sibling::node()">
<xsl:copy>
<xsl:apply-templates select="@* | separator[last()]/following-sibling::node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="separator" mode="split">
<xsl:apply-templates select=".." mode="split">
<xsl:with-param name="separator" select="."/>
</xsl:apply-templates>
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="*" mode="split">
<xsl:param name="separator"/>
<xsl:copy>
<xsl:apply-templates select="@* | key('sep', generate-id($separator))"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/pPqsHTc
请注意,如果您使用 Xalan Java,那么在 Java 世界中,使用 Saxon 9 和 XSLT 2/3 的 <xsl:for-each-group select="node()" group-adjacent= 会容易得多"boolean(self::separator)">
或 group-starting-with="separator"
.
Note that if you use Xalan Java then in the Java world this is much easier with Saxon 9 and XSLT 2/3's <xsl:for-each-group select="node()" group-adjacent="boolean(self::separator)">
or group-starting-with="separator"
.
这篇关于XSLT 通过 splitter-element 拆分元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!