xslt& xpath:直接匹配前面的注释

时间:2010-06-07 16:10:12

标签: xml xslt xpath

我正在尝试将XSLT转换应用于一批XML文档。转换的要点是重新排序几个元素。我希望保留直接在元素之前的任何评论:

<!-- not this comment -->
<element />

<!-- this comment -->
<!-- and this one -->
<element />

我最接近解决方案的方法是使用表达式:

<xsl:template match="element">
    <xsl:copy-of select="preceding-sibling::comment()"/>
</xsl:template>

抓住了太多评论:

<!-- not this comment -->
<!-- this comment -->
<!-- and this one -->

我理解为什么前面提到的XPath无法正常工作,但我对如何继续操作没有任何好的想法。我正在寻找的是选择所有前面的注释,其后续兄弟是另一个注释或正在处理的当前元素:

preceding-sibling::comment()[following-sibling::reference_to_current_element() or following-sibling::comment()]

2 个答案:

答案 0 :(得分:5)

<xsl:template match="element">
  <xsl:copy-of select="preceding-sibling::comment()[
    generate-id(following-sibling::*[1]) = generate-id(current())
  "/>
</xsl:template>

效率更高:

<xsl:key 
  name  = "kPrecedingComment" 
  match = "comment()" 
  use   = "generate-id(following-sibling::*[1])" 
/>

<!-- ... -->

<xsl:template match="element">
  <xsl:copy-of select="key('kPrecedingComment', generate-id())" />
</xsl:template>

答案 1 :(得分:1)

我认为最好的方法如下:

我想要预先注释的注释,但只有当前节点作为第一个元素才能跟随它们。

然后,在xpath1.0 / xslt1.0:

<xsl:template match="element">
<xsl:copy-of select="preceding-sibling::comment()[count(following-sibling::*[1]|current()) = 1]"/>
</xsl:template>