Specific attributes in XPath
Hi,
I am trying to select a element which attribute "name" has a value "test". However, there is an awful error showing up. Anyone willing to help? :(nod):
Example XML:
Code:
<row id="1" name="test" />
My code so far:
The error:
Code:
Exception in thread "main" javax.xml.transform.TransformerException: A location path was expected, but the following token was encountered: ]
at com.sun.org.apache.xpath.internal.compiler.XPathParser.error(XPathParser.java:608)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.LocationPath(XPathParser.java:1599)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.PathExpr(XPathParser.java:1315)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnionExpr(XPathParser.java:1234)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnaryExpr(XPathParser.java:1140)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.MultiplicativeExpr(XPathParser.java:1061)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.AdditiveExpr(XPathParser.java:1003)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.RelationalExpr(XPathParser.java:928)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.EqualityExpr(XPathParser.java:868)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.AndExpr(XPathParser.java:832)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.OrExpr(XPathParser.java:805)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.Expr(XPathParser.java:788)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.PredicateExpr(XPathParser.java:1952)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.Predicate(XPathParser.java:1934)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.Step(XPathParser.java:1724)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.RelativeLocationPath(XPathParser.java:1633)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.LocationPath(XPathParser.java:1595)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.PathExpr(XPathParser.java:1315)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnionExpr(XPathParser.java:1234)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnaryExpr(XPathParser.java:1140)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.MultiplicativeExpr(XPathParser.java:1061)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.AdditiveExpr(XPathParser.java:1003)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.RelationalExpr(XPathParser.java:928)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.EqualityExpr(XPathParser.java:868)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.AndExpr(XPathParser.java:832)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.OrExpr(XPathParser.java:805)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.Expr(XPathParser.java:788)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.initXPath(XPathParser.java:127)
at com.sun.org.apache.xpath.internal.XPath.<init>(XPath.java:176)
at com.sun.org.apache.xpath.internal.XPath.<init>(XPath.java:264)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.compile(XPathImpl.java:394)
Re: Specific attributes in XPath
You didn't post your Java code.
Re: Specific attributes in XPath
Sorry...
Code:
String XPathExpression = "/row/@name='test'";
String XMLUrl = "urltofile";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new URL(XMLUrl).openStream());
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile(XPathExpression);
Object result = expr.evaluate(document, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
resultArray[i] = nodes.item(i).getNodeValue();
}
for (int i = 0; i < resultArray.length; i++) {
System.out.println(resultArray[i]);
}
Re: Specific attributes in XPath
Code:
String XPathExpression = "/row/@name='Test'";
Your test is wrong.
That should (IIRC) be in square brackets.
Code:
String XPathExpression = "/row[@name='Test']";
Re: Specific attributes in XPath
I changed it. Now the array returns null.
Basically, what I want to do is to select an row that has "name" attribute "test" (there are many rows with different names) and get all its attributes values (in the example it is only id, but actually there can be more attributes in each row).
Re: Specific attributes in XPath
What does your test XML look like?
The other option (if 'row' is not a top level element) is use a double slash, so it searches right down the tree.
Re: Specific attributes in XPath
This is the actual XML:
Code:
<eveapi version="2">
<currentTime>2012-02-09 16:40:28</currentTime>
<result>
<rowset name="characters" key="characterID" columns="name,characterID,corporationName,corporationID">
<row name="characterName1" characterID="1111111111" corporationName="corpName1" corporationID="11111111"/>
<row name="characterName2" characterID="2222222222" corporationName="corpName2" corporationID="22222222"/>
</rowset>
</result>
<cachedUntil>2012-02-09 17:11:12</cachedUntil>
</eveapi>
I want to select a row where name is eg. "characterName1" and get this row's characterID.
Re: Specific attributes in XPath
Which would have been helpful, as 'row' is clearly not a top element.
You'll need "//row[@name='test']".
Re: Specific attributes in XPath
Ok, I still get "null" from the returned array.
Re: Specific attributes in XPath
You'll have to play around with it.
Could be namespaces, typos, anything.
Re: Specific attributes in XPath
I presume you're not actually using 'test' against that data above?
Re: Specific attributes in XPath
Re: Specific attributes in XPath
OK:
Code:
String xml = "<eveapi version=\"2\"> <currentTime>2012-02-09 16:40:28</currentTime> <result> <rowset name=\"characters\" key=\"characterID\" columns=\"name,characterID,corporationName,corporationID\"> <row name=\"characterName1\" characterID=\"1111111111\" corporationName=\"corpName1\" corporationID=\"11111111\"/> <row name=\"characterName2\" characterID=\"2222222222\" corporationName=\"corpName2\" corporationID=\"22222222\"/> </rowset> </result> <cachedUntil>2012-02-09 17:11:12</cachedUntil> </eveapi>";
String XPathExpression = "//row[@name='characterName1']";
String XMLUrl = "urltofile";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(xml.getBytes()));
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile(XPathExpression);
Object result = expr.evaluate(document, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
System.out.println(nodes.getLength());
That prints out 1.
The String contains the xml you posted above, and the expression is what I suggested (modified to take into account the data).
If it doesn't work on yours then there is something else going on I can't see.
Re: Specific attributes in XPath
Here is the code that I use:
Code:
String XPathExpression = "/row/@name='test'";
String XMLUrl = "urltofile";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new URL(XMLUrl).openStream());
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile(XPathExpression);
Object result = expr.evaluate(document, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
resultArray[i] = nodes.item(i).getNodeValue();
}
for (int i = 0; i < resultArray.length; i++) {
System.out.println(resultArray[i]);
}
The code works with XPaths such as "//row/@*" (lists values of all attributes in all rows) but with "//row[@name='characterName1'] it gives me one null value. I would like it to list all values in that row.
UP: well, since it contains one null value, it prints out 1...
Re: Specific attributes in XPath
Code:
for (int i = 0; i < nodes.getLength(); i++) {
Element n = (Element) nodes.item(i);
System.out.println(n.getAttribute("name"));
}
That prints out the value of "name", which is characterName1.
The default implementation getNodeValue() displays null (for some reason I can't fathom), so you can't rely on it.
So cast to an Element (since that's what you;re working with) and use the methods on there.
Re: Specific attributes in XPath
I get this error:
Code:
Exception in thread "main" java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.DeferredElementImpl cannot be cast to javax.lang.model.element.Element
Re: Specific attributes in XPath
I still have no idea why I get this error. Could someone please help?
Re: Specific attributes in XPath
It's pretty explicit:
Quote:
java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.DeferredEle mentImpl cannot be cast to javax.lang.model.element.Element
You probably imported the wrong Element class.
db
Re: Specific attributes in XPath
Thanks. Everything works now when I changed the import.
Re: Specific attributes in XPath
Hi,
I have read all these post answers (or replies) but I have found anything related of
how to extract element attributes. I have, for example, this Yahoo! weather information:
Code:
<yweather:forecast day="Tue" date="24 Apr 2012" low="9" high="17" text="Cloudy" code="26" />
(
full rss)
I have tried using this code:
Code:
public static void extractValuesFromYWeatherUsingXPath( String woeid ) throws ParserConfigurationException, SAXException, XPathExpressionException, IOException
{
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware( true );
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse( "http://weather.yahooapis.com/forecastrss?w=" + woeid + "&u=c" );
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr = xpath.compile( "//yweather:forecast/@*" );
Object result = expr.evaluate( doc, XPathConstants.NODESET );
NodeList attributes = (NodeList) result;
System.out.println( "Tamahnio: " + attributes.getLength() );
for (int i = 0; i < attributes.getLength(); i++ )
{
Attr attr = (Attr) attributes.item(i);
System.out.println( "Name: " + attr.getName() + " - Value: " + attr.getValue() );
}
}
But the results are not I have expected (
Tue (from day),
24 Apr 2002 (from date)
9 (from low),
17 (from high),
Cloudy (from text), and
26 (from code)).
Some suggestions about this case? Thanks in advance for any help.
So long.