0

I have been trying to figure out this solution online. I am finding out the most efficient way of parsing an XML file.

The following is my XML file:

<?xml version="1.0" encoding="UTF-8"?>
<game>
    <person>
       <name>ABC</name>
       <address>XYZ</address>
       <age>35</age>
    </person>
    <place>
       <country>US</country>
       <state>California</state>
       <city>Fremont</city>
    </place>
    <thing>
       <name>Book</name>
       <use>Read and write</use>
    </thing>
</game>

I have to parse this XML file using xPath in Java. I would like to have /*[i] as the xPath expression where i is an integer and 0<i<4. Also I would like to display the whole "chunk" of XML. That is if i=1, then the expression has to return <country>US</country><state>California</state><city>Fremont</city>. Please help me out with this.Please do NOT use DOM (Ex. Node class) for this in any of the steps of your solution. Also please try to use Apache Commons framework as it uses SAX Parser internally.

Thanks.

  • The XPath expression `/*` selects the root element, there is only exactly one root element in any XML document so only `/*[1]` would select anything, `/*[2]` and higher would not select anything. – Martin Honnen Jan 30 '16 at 08:55
  • / means root element and * after / would indicate any child of the root element. But the index(i) would mean the ith child from the root – Bill Hargreaves Jan 30 '16 at 09:41
  • No, `/` selects the root node respectively document node, not the root element. And even `/*/*[1]` would not select what you say you want, as in the sample you have posted the first child element of the root element is the `person` element, not any `country` or `state` or `city` elements. – Martin Honnen Jan 30 '16 at 10:35
  • I might be wrong.......Plz suggest me a solution – Bill Hargreaves Jan 30 '16 at 10:54
  • How to return the whole chunk of XML? Do I have to use XPath , XPathFactory ,XPath expression engine etc.? – Bill Hargreaves Jan 30 '16 at 10:58
  • 1
    XPath is a query language based on a data model of an XML document. It needs to be embedded in some higher language/API such as DOM, XOM, JDOM, XSLT, etc. in order to display anything; and the details of how you do this will depend on that higher level API, though the XPath expression will be the same in all cases. SAX will not work here since it does not provide a model of the complete document as a single object, but rather a stream of events. – Elliotte Rusty Harold Jan 30 '16 at 11:40
  • `
    ` is not correctly closed. Your input is invalid
    – pouyan Jan 30 '16 at 12:56
  • Now it is valid.Thanks – Bill Hargreaves Jan 30 '16 at 14:22

1 Answers1

0

This is your appropriate xpath:

/game/child::*[position() = $i]

Supposing $i referring to value of variable i

  • Note that $i starting from 1

You can use jaxp xpath to implement that.

pouyan
  • 307
  • 1
  • 5
  • I tried it out. But this doesn't give me the sub-elements(sub-tags), it only gives me the values in the sub-elements. That is "US California Fremont" as the result. But I would like to have "USCaliforniaFremont" as the result. – Bill Hargreaves Jan 30 '16 at 13:15
  • @BillHargreaves that's because the way you are evaluating the xpath. You are getting the *value* (stringified result) instead of getting the *node-list* itself. Please dump the way you are getting it – pouyan Jan 30 '16 at 13:20
  • @BillHargreaves You should use xpath evaluation function in your library which returns NodeList, not string. A solution is described in: http://stackoverflow.com/questions/2811001 – pouyan Jan 30 '16 at 13:35
  • But again, converting Node/NodeList into String is a costly operation. Imagine if there are 100,000 children(repeatable) for . – Bill Hargreaves Jan 30 '16 at 13:53
  • @BillHargreaves expand your xpath to match all desired nodes or use xslt to build the output and then dump it all via `domDocument->saveXml(domNode);` – pouyan Jan 31 '16 at 05:59
  • XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expression = xpath.compile("/configuration/child::*[position() = 2]"); Node result =(Node) expression.evaluate(new org.xml.sax.InputSource("Sample.xml"),XPathConstants.NODE); System.out.println(result); – Bill Hargreaves Jan 31 '16 at 07:07