如何使用 XSLT 根据前一个兄弟元素包装一组相邻元素?
How can I wrap a group of adjacent elements depending on the previous sibling using XSLT?
我想包装所有的附录元素,但前提是第一个附录元素的前一个兄弟元素是一部分。
所以如果输入像
<part>
..
..
</part>
<appendix href="..">
</appendix>
<appendix href="..">
</appendix>
那么输出就像
<part>
..
..
</part>
<appendices>
<appendix href="..">
</appendix>
<appendix href="..">
</appendix>
</appendices>
我对 XSLT 还很陌生。所以到目前为止,我所尝试的一切都失败了。任何帮助将不胜感激。
使用 XSLT 2.0,您的口头描述可以转化为
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="*[appendix]">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(self::appendix)">
<xsl:choose>
<xsl:when test="current-grouping-key() and preceding-sibling::*[1][self::part]">
<appendices>
<xsl:apply-templates select="current-group()"/>
</appendices>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
我想包装所有的附录元素,但前提是第一个附录元素的前一个兄弟元素是一部分。
所以如果输入像
<part>
..
..
</part>
<appendix href="..">
</appendix>
<appendix href="..">
</appendix>
那么输出就像
<part>
..
..
</part>
<appendices>
<appendix href="..">
</appendix>
<appendix href="..">
</appendix>
</appendices>
我对 XSLT 还很陌生。所以到目前为止,我所尝试的一切都失败了。任何帮助将不胜感激。
使用 XSLT 2.0,您的口头描述可以转化为
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="*[appendix]">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(self::appendix)">
<xsl:choose>
<xsl:when test="current-grouping-key() and preceding-sibling::*[1][self::part]">
<appendices>
<xsl:apply-templates select="current-group()"/>
</appendices>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>