I'm trying to do a xpath lookup on nodes returned by xpath lookup, but it doesn't seem to work as I expected.XPaths executed on the child nodes of a document seem to be executd against hthe root node of the document (in the example, the inventory tag.), instead of the root of the provided node.
Am I missing something here? I'm new to XPath.
Also, please don't answer "just do //book[author='Neal Stephenson'/title". I have a legitimate use case, and this is a simplified example.
Code snippet
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse("src/main/java/books.xml"); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); Node book = (Node) xpath.evaluate("//book[author='Neal Stephenson']", doc, XPathConstants.NODE); Node title = (Node) xpath.evaluate("/title", book, XPathConstants.NODE); // I get null here. Node inventory = (Node) xpath.evaluate("/inventory", book, XPathConstants.NODE); // this returns a node.
book.xml
<inventory> <book year="2000"> <title>Snow Crash</title> <author>Neal Stephenson</author> <publisher>Spectra</publisher> <isbn>0553380958</isbn> <price>14.95</price> </book> <book year="2005"> <title>Burning Tower</title> <author>Larry Niven</author> <author>Jerry Pournelle</author> <publisher>Pocket</publisher> <isbn>0743416910</isbn> <price>5.99</price> </book> <book year="1995"> <title>Zodiac</title> <author>Neal Stephenson</author> <publisher>Spectra</publisher> <isbn>0553573862</isbn> <price>7.50</price> </book> <!-- more books... --> </inventory>
For the div element with an id attribute of hero //div[@id='hero'] , these XPath expression will select elements as follows: //div[@id='hero']/* will select all of its children elements. //div[@id='hero']/img will select all of its children img elements. //div[@id='hero']//* will select all of its descendent elements.
XPath is a mini-language that describes a node pattern to select a set of nodes. Descendant is declared as ' // ' so a child can be defined as a// b, to go deeper into the XML tree descendant gives away. Syntax: Web development, programming languages, Software testing & others.
In XPath, the parent node of the current node selected in the web page is retrieved using the Parent method. It comes in handy when we choose an element and need to utilise Xpath to fetch the parent element. This method can also be used to find out who the parent's parents are and abbreviated as (..).
The key part of this XPath is *[1] , which will select the node value of the first child of Department .
/foo
will select based off of the root node, ignoring the context that you are evaluating the xpath against. foo
(without the slash) is what you want; that selects based off of the current node.
https://www.w3schools.com/xml/xpath_syntax.asp gives a bit more info.
in Xpath, "." (Dot) represents the current document. So, write your XPATH string after a "." (Dot) .
ex :
"./title"
or
".//title"
Whatever you want....
removing the slash works only if its a child of the node. What if you want to use the // (wherever in the current Document) functionality ?
So, use the dot (.)
Thanks a lot for the above answers too :) .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With