我正在尝试使用XSLT对XML文档进行排序,并希望保留这些注释。到目前为止一直很好,因为这个问题已经有了一些答案(见相关......)。 但是!这些(优秀的)答案都没有涉及到这样的XML:
<xml>
<beatles>
<!-- comment(1): john is actually my favourite -->
<!-- comment(2): John died tragically in 1980 -->
<beatle name="John"/>
<beatle name="Ringo"/>
<beatle name="George"/>
<!-- comment(1): Paul still does live concerts to this day -->
<!-- comment(2): contrary to common folklore, Paul is NOT dead! -->
<beatle name="Paul"/>
</beatles>
</xml>
现在发生了什么?我想通过名字对甲壳虫乐队(上帝保佑他们)进行排序,并保留每个甲壳虫乐队的所有评论,以便得到这个结果:
<xml>
<beatles>
<beatle name="George"/>
<!-- comment(1): john is actually my favourite -->
<!-- comment(2): John died tragically in 1980 -->
<beatle name="John"/>
<!-- comment(1): Paul still does live concerts to this day -->
<!-- comment(2): contrary to common folklore, Paul is NOT dead! -->
<beatle name="Paul"/>
<beatle name="Ringo"/>
</beatles>
</xml>
好老前兄弟::评论()[1] 在这里不起作用。在常规代码中,我只对所有前面的注释执行反向循环,并在我点击非注释节点时停止;但众所周知,XSLT的 for-each 无法转义。
有什么想法吗?
TIA!
DF。
答案 0 :(得分:1)
我认为这可以通过一个键来实现,该键列出给定'beatle'元素的所有注释。
<xsl:key name="comments" match="comment()" use="following-sibling::beatle[1]/@name" />
因此,对于每个评论,它都是由第一个连续的beatle元素索引。
然后您可以按如下方式使用此列表来列出任何beatle元素的所有注释。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:key name="comments" match="comment()" use="following-sibling::beatle[1]/@name" />
<xsl:template match="/xml/beatles">
<beatles>
<xsl:for-each select="beatle">
<xsl:sort select="@name" />
<!-- Loop through all comments for the beatle element -->
<xsl:for-each select="key('comments', @name)">
<xsl:comment>
<xsl:value-of select="." />
</xsl:comment>
</xsl:for-each>
<!-- Copy the beatle element -->
<xsl:copy>
<xsl:copy-of select="@*" />
</xsl:copy>
</xsl:for-each>
</beatles>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
复制相应的beatle
节点时,您也应该应用其注释。这就是你需要做的。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="beatles">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="beatle">
<xsl:sort select="@name" data-type="text"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="beatle">
<xsl:variable name="current" select="."/>
<xsl:apply-templates
select="preceding-sibling::comment()[generate-id(following-sibling::beatle[1]) = generate-id($current)]"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="windows-1251"?>
<xml>
<beatles>
<beatle name="George"/>
<!-- comment(1): john is actually my favourite -->
<!-- comment(2): John died tragically in 1980 -->
<beatle name="John"/>
<!-- comment(1): Paul still does live concerts to this day -->
<!-- comment(2): contrary to common folklore, Paul is NOT dead! -->
<beatle name="Paul"/>
<beatle name="Ringo"/>
</beatles>
</xml>