Xslt & xpath: matching immediately preceding comments

I am trying to apply an XSLT transform to XML batch documentation. The main point of the transformation is the reordering of several elements. I want to keep any comments that immediately precede the element:

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

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

The closest I came to a solution was to use the expression:

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

which captures too many comments:

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

I understand why the aforementioned XPath does not work correctly, but I have no good ideas on how to proceed. What I'm looking for is something to select all previous comments, the next of which is either another comment or the current item being processed:

preceding-sibling::comment()[following-sibling::reference_to_current_element() or following-sibling::comment()]
+3
2
<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>
+5

, :

, , node, , .

xpath1.0/xslt1.0:

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

Source: https://habr.com/ru/post/1748873/


All Articles