Search code examples
xmlxpathdom4j

Get directly previous XML comment with XPath


I'm trying to detect whether an element has a comment directly preceding it.

I was using preceding-sibling::comment()[last()], but that wouldn't be accurate in the case of the "B" element below:

<!-- Comment for A -->
<string name="A">A</string>
<string name="B">B</string>

What is the correct way to do this?


Solution

  • test="( preceding-sibling::* | preceding-sibling::comment() )[last()][self::comment()]"

    This takes the union of all preceding-sibling elements and comments, takes the last of them, and returns the last of them if it is a comment, and the test returns true() because the returned node set is non-empty.

    Note that if I wasn't using the union operator, preceding-sibling::comment()[1] returns the closest because a predicate applied to a location step is in proximity order. Your use of [last()] returns the farthest comment, not the closest comment. In my test above the union is in document order (because it isn't a location step, it is the union of two location steps), not proximity order, so I have to use [last()] and not [1].