Using //

J

JS

I have this XML file:

<root>
<lines>
<line order="0">
<content id="A" value="0_A"/>
<content id="B" value="0_B"/>
<content id="C" value="0_C"/>
<content id="D" value="0_D"/>
<content id="E" value="0_E"/>
</line>
<line order="1">
<content id="A" value="1_A"/>
<content id="B" value="1_B"/>
<content id="C" value="1_C"/>
<content id="D" value="1_D"/>
<content id="E" value="1_E"/>
</line>
</lines>
</root>


From Java I am trying to print values for all elements where ID = "A":

public void test(){
javax.xml.xpath.XPathFactory factory =
javax.xml.xpath.XPathFactory.newInstance();
javax.xml.xpath.XPath xpath = factory.newXPath();
javax.xml.xpath.XPathExpression expression;
String result;
try {
expression = xpath.compile("//content[@id =\"A\"]/@value");
URL url = this.getClass().getClassLoader().getResource("test.xml");
String path = url.toURI().getPath();
result = expression.evaluate(new org.xml.sax.InputSource(path));
System.out.println("result is = " + result);
} catch (Exception e) {
e.printStackTrace();
}
}


But only:

0_A

is printed. Does "//" not mean that all 'content' elements are chosen?
 
M

Martin Honnen

JS said:
From Java I am trying to print values for all elements where ID = "A":

public void test(){
javax.xml.xpath.XPathFactory factory =
javax.xml.xpath.XPathFactory.newInstance();
javax.xml.xpath.XPath xpath = factory.newXPath();
javax.xml.xpath.XPathExpression expression;
String result;
try {
expression = xpath.compile("//content[@id =\"A\"]/@value");
URL url = this.getClass().getClassLoader().getResource("test.xml");
String path = url.toURI().getPath();
result = expression.evaluate(new org.xml.sax.InputSource(path));
System.out.println("result is = " + result);
} catch (Exception e) {
e.printStackTrace();
}
}


But only:

0_A

is printed. Does "//" not mean that all 'content' elements are chosen?

There is an overload
http://xml.apache.org/xalan-j/apido...l.sax.InputSource, javax.xml.namespace.QName)
of the evaluate method where the second argument allows you to choose a
result different from a string so use that to select
javax.xml.xpath.XPathConstants.NODESET as the return type, then I think
you can cast the returned object to a DOM NodeList and iterate over that
node list to access all selected nodes.

The method you currently use converts the selected node-set to a string
and that, with XPath 1.0, means you always get the string value of the
first node in the node-set.
 
J

JS

Martin Honnen said:
JS said:
From Java I am trying to print values for all elements where ID = "A":

public void test(){
javax.xml.xpath.XPathFactory factory =
javax.xml.xpath.XPathFactory.newInstance();
javax.xml.xpath.XPath xpath = factory.newXPath();
javax.xml.xpath.XPathExpression expression;
String result;
try {
expression = xpath.compile("//content[@id =\"A\"]/@value");
URL url = this.getClass().getClassLoader().getResource("test.xml");
String path = url.toURI().getPath();
result = expression.evaluate(new org.xml.sax.InputSource(path));
System.out.println("result is = " + result);
} catch (Exception e) {
e.printStackTrace();
}
}


But only:

0_A

is printed. Does "//" not mean that all 'content' elements are chosen?

There is an overload
http://xml.apache.org/xalan-j/apido...l.sax.InputSource, javax.xml.namespace.QName)
of the evaluate method where the second argument allows you to choose a
result different from a string so use that to select
javax.xml.xpath.XPathConstants.NODESET as the return type, then I think
you can cast the returned object to a DOM NodeList and iterate over that
node list to access all selected nodes.


The closest I coud find was NodeList:
NodeList list = (NodeList) expression.evaluate(new
org.xml.sax.InputSource(path), javax.xml.xpath.XPathConstants.NODESET);

for (Object obj : list) {
System.out.println((String)obj);

}

But that object is not iterable.


The method you currently use converts the selected node-set to a string
and that, with XPath 1.0, means you always get the string value of the
first node in the node-set.

Ok but if I use XPath 2.0 would I then get the full result set?
 
M

Martin Honnen

JS said:
The closest I coud find was NodeList:
NodeList list = (NodeList) expression.evaluate(new
org.xml.sax.InputSource(path), javax.xml.xpath.XPathConstants.NODESET);

for (Object obj : list) {
System.out.println((String)obj);

}

I think
for (int i = 0, int l = list.getLength(); i < l; i++)
{
XmlAttribute att = (XmlAttribute)list.getItem(i);
System.out.println(att.getNodeValue());
}
should do but I mostly use the W3C DOM with JavaScript so take the above
as pseudo code, not as compiled Java code.
Ok but if I use XPath 2.0 would I then get the full result set?

You get the full set of nodes even with XPath 1.0 if you use the right
method that returns a node-set
..
The difference I mentioned is with taking the string value of a node-set
(which the method you have implictly does) where XPath 1.0 takes the
string value of the first node in the node-set.

I thought with XPath 2.0 you would get the string concatenation of all
nodes in the sequence as what is the result you get with XSLT 2.0 and
xsl:value-of but it looks to be more complicated, with XPath 2.0
string(sequence-of-more-than-one-node) is not allowed. I don't know what
that API you use would do with an XPath 2.0 implementation, I think
Michal Kay's Saxon allows you to use that API with XPath 2.0 but he
always recommends to use Saxon's own API tailored to the XPath 2.0 data
model.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top