1

Using XPath, I want to get those comments which are the first children of item elements, before any other element children.

I have XML like this:

<list>
    ...
    <item id="52">
        <!-- this is optional comment, need get this -->
        <randomParam>asd</randomParam> <!-- not this comment -->
        <anotherRandomParam type="3" />
        <paramText /> <!-- not this comment -->
        ...
    </item>
    <item id="53">
        <param1>test</param1> <!-- not need this comment -->
        <param2 title="text">text</param2>
        <someParam>
        <!-- not need this comment -->
                <test />
                <test /> 
                <test />
        </someParam>
        ...
    </item>
    ...
</list>
kjhughes
  • 106,133
  • 27
  • 181
  • 240
PlayerKillerYKT
  • 294
  • 2
  • 12

1 Answers1

1

This XPath,

//item/comment()[not(preceding-sibling::*)]

will select all comment() children of item elements that have no preceding element siblings,

<!-- this is optional comment, need get this -->

as requested.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • i try in XPath online and get `TypeError: Cannot read property 'childPosition' of undefined`, element() its not xpath function? – PlayerKillerYKT Mar 11 '21 at 20:29
  • I'll venture to guess you've gotten that result on [xpather.com](http://xpather.com/), which is [known to fail to implement the XPath standard faithfully.](https://stackoverflow.com/a/59215146/290085)... ...confirmed. Avoid xpather.com -- it's non-compliant with the XPath standard. If you use a compliant XPath site or library, you'll find that the above XPath works perfectly well. – kjhughes Mar 11 '21 at 20:47
  • Yes, but in PHP(which use libxml) i got warning: `DOMXPath::query(): Invalid expression [...][...]`, i think need replace `element()` to `*`, or `node()` can be used too under option `preserveWhiteSpace=false` – PlayerKillerYKT Mar 11 '21 at 20:58
  • @PlayerKillerYKT: `element()` requires XPath 2.0, and libxml only supports XPath 1.0. Yes, you can use `*` so that the above XPath will work with XPath 1.0 and up. Answer updated. This still doesn't absolve xpather.com, which still fails with `*`. – kjhughes Mar 11 '21 at 21:01
  • Сan you answer pls, if there may be several comments before other elements, how i can get multiple? Like this: `test`. – PlayerKillerYKT Mar 11 '21 at 21:26
  • The XPath in the answer would select both of those comments already. Be sure to be using a library call that can return multiple results, not just select the first one. – kjhughes Mar 11 '21 at 21:54