我有一个 xml 文档,在层次结构的深处有分隔符。
<A>
<B>
<C id='1'/>
<separator/>
<C id='2'/>
</B>
<B>
<C id='3'/>
<separator/>
</B>
<B>
<C id='4'/>
</B>
</A>
我想向上移动分隔符,使元素保持有序。所以期望的输出是
<A>
<B>
<C id='1'/>
</B>
</A>
<separator/>
<A>
<B>
<C id='2'/>
</B>
<B>
<C id='3'/>
</B>
</A>
<separator/>
<A>
<B>
<C id='4'/>
</B>
</A>
仅使用 xslt 1.0 如何完成?可以不使用 for-each
,仅使用模板匹配来完成吗?
更新: 我实际上得到了 4 个不同程度的概括的精彩答案,谢谢你们,伙计们。
最佳答案
这个转换:
<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:key name="kFollowing" match="C"
use="generate-id(preceding::separator[1])"/>
<xsl:template match="/">
<xsl:apply-templates select="*/*/separator"/>
</xsl:template>
<xsl:template match="separator" name="commonSep">
<separator/>
<xsl:call-template name="genAncestors">
<xsl:with-param name="pAncs" select="ancestor::*"/>
<xsl:with-param name="pLeaves"
select="key('kFollowing', generate-id())"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="separator[not(preceding::separator)]">
<xsl:call-template name="genAncestors">
<xsl:with-param name="pAncs" select="ancestor::*"/>
<xsl:with-param name="pLeaves"
select="key('kFollowing', '')"/>
</xsl:call-template>
<xsl:call-template name="commonSep"/>
</xsl:template>
<xsl:template name="genAncestors">
<xsl:param name="pAncs" select="ancestor::*"/>
<xsl:param name="pLeaves" select="."/>
<xsl:choose>
<xsl:when test="not($pAncs[2])">
<xsl:apply-templates select="$pLeaves" mode="gen"/>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="$pAncs[1]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:call-template name="genAncestors">
<xsl:with-param name="pAncs" select="$pAncs[position()>1]"/>
<xsl:with-param name="pLeaves" select="$pLeaves"/>
</xsl:call-template>
</xsl:copy>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="C" mode="gen">
<xsl:variable name="vCur" select="."/>
<xsl:for-each select="..">
<xsl:copy>
<xsl:copy-of select="@*|$vCur"/>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<A>
<B>
<C id='1'/>
<separator/>
<C id='2'/>
</B>
<B>
<C id='3'/>
<separator/>
</B>
<B>
<C id='4'/>
</B>
</A>
产生想要的、正确的结果:
<A>
<B>
<C id="1"/>
</B>
</A>
<separator/>
<A>
<B>
<C id="2"/>
</B>
<B>
<C id="3"/>
</B>
</A>
<separator/>
<A>
<B>
<C id="4"/>
</B>
</A>
关于xml - 在 xml 层次结构中向上移动分隔符元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3863274/