我有一个需要一些XSLT转换的XML文档。 这是XML:
<docs>
<!-comment->
<doc>
<node add="1"/>
<node add="2"/>
<!-comment->
<node add="3"/>
<node add="4"/>
<node add="5"/>
<!-comment->
<node add="6"/>
<node add="7"/>
<node add="8"/>
</doc>
</docs>
转换后,以上结构应如下所示:
<docs>
<!-comment->
<doc>
<node add="1"/>
<node add="2"/>
</doc>
<!-comment->
<doc>
<node add="3"/>
<node add="4"/>
<node add="5"/>
</doc>
<!-comment->
<doc>
<node add="6"/>
<node add="7"/>
<node add="8"/>
</doc>
</docs>
到目前为止,我的代码是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@* , node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="docs">
<xsl:for-each select="comment">
<doc>
<xsl:copy-of select="following-sibling::node[not(following-sibling::comment)]"/>
<doc>
<xsl:for-each>
</xsl:template>
此代码确实复制了节点,但是它复制了注释后的所有节点(这是错误的)。从结构上讲,我可以说出我在做错什么,但是我无法提出正确的模式来对节点进行分组并相应地放置它们。而且,节点数可以针对不同的XML进行更改。
答案 0 :(得分:1)
针对这些情况发明了XSLT元素xsl:for-each-group
。有关更多信息,请参见https://www.saxonica.com/html/documentation/xsl-elements/for-each-group.html。
我的解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc">
<xsl:for-each-group select="node|comment()" group-starting-with="comment()">
<xsl:copy-of select="current-group()[self::comment()]"/>
<doc>
<xsl:copy-of select="current-group()[self::element()]"/>
</doc>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>