0

So I have an XML file here, and I want to get a value from it using XPath. The file in question is an XML file in a zip that you can download here:

I believe that it's valid XML.

My current goal is to parse out the last (newest) LMP_PRC value in the document.

My current code looks like this and returns an empty string every time:

XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expr = xpath.compile("//m:OASISReport/m:MessagePayload/m:RTO/m:REPORT_ITEM[3]/m:REPORT_DATA[/m:DATA_ITEM='LMP_PRC'][last()]/m:VALUE/text()") ; String result = (String) expr.evaluate(doc, XPathConstants.STRING); 

The m:REPORT_ITEM[3] has been an area of confusion for me so I've tried it with just about every number and have had no luck with it.

1 Answer 1

1

The m:REPORT_ITEM[3] just means the 3rd one that matches. You're not getting any matches because of:

m:REPORT_DATA[/m:DATA_ITEM='LMP_PRC'][last()] 

You want the relative path from there, not the absolute path:

m:REPORT_DATA[m:DATA_ITEM='LMP_PRC'][last()] 

So the whole thing would look like:

//m:OASISReport/m:MessagePayload/m:RTO/m:REPORT_ITEM[3]/m:REPORT_DATA[m:DATA_ITEM='LMP_PRC'][last()]/m:VALUE/text() 

The other thing to deal with is the namespace resolution. For a good summary of what is happening in your case, see http://blog.davber.com/2006/09/17/xpath-with-namespaces-in-java/. So you should add something like:

private static NamespaceContext getNamespaceContext() { NamespaceContext namespaceContext = new NamespaceContext() { public String getNamespaceURI(String prefix) { String uri = null; if (prefix == null) { throw new IllegalArgumentException("No prefix provided!"); } else if(prefix.equals("m")) { uri = "http://oasis.caiso.com/mrtu-oasis/xsd/OASISReport.xsd"; } return uri; } @SuppressWarnings("rawtypes") @Override public Iterator getPrefixes(String namespaceURI) { // TODO Auto-generated method stub return null; } @Override public String getPrefix(String namespaceURI) { // TODO Auto-generated method stub return null; } }; return namespaceContext; } 

And then use that method to set the namespace context on your xpath object:

xpath.setNamespaceContext(getNamespaceContext()); 
Sign up to request clarification or add additional context in comments.

2 Comments

With the code above followed by a System.out.println() I'm not getting anything from the code you posted. XPath xpath = factory.newXPath(); XPathExpression expr = xpath.compile("//m:OASISReport/m:MessagePayload/m:RTO/m:REPORT_ITEM[3]/m:REPORT_DATA[m:DATA_ITEM='LMP_PRC'][last()]/m:VALUE/text()") ; String result = (String) expr.evaluate(doc, XPathConstants.STRING); System.out.println("Last value: " + result ) ;
Edited answer to include namespace resolution. If you want it to be more sophisticated than what I put up there, see ibm.com/developerworks/java/library/x-nmspccontext/index.html

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.