I spent the last day trying to extract one XML node from the following document and was not able to understand the nuances of the XML namespaces to make it work.
The XML file should be published as a whole, so here is the part that interests me:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <XFDL xmlns="http://www.PureEdge.com/XFDL/6.5" xmlns:custom="http://www.PureEdge.com/XFDL/Custom" xmlns:designer="http://www.PureEdge.com/Designer/6.1" xmlns:pecs="http://www.PureEdge.com/PECustomerService" xmlns:xfdl="http://www.PureEdge.com/XFDL/6.5"> <globalpage sid="global"> <global sid="global"> <xmlmodel xmlns:xforms="http://www.w3.org/2003/xforms"> <instances> <xforms:instance id="metadata"> <form_metadata> <metadataver version="1.0"/> <metadataverdate> <date day="05" month="Jul" year="2005"/> </metadataverdate> <title> <documentnbr number="2062" prefix.army="DA" scope="army" suffix=""/> <longtitle>HAND RECEIPT/ANNEX NUMBER </longtitle> </title>
The document continues and is fully formed to the end. I am trying to extract the attribute "number" from the tag "documentnbr" (three from the bottom).
The code I use for this is as follows:
public String getFormNumber() throws InvalidFormException { try{ XPath xPath = XPathFactory.newInstance().newXPath(); xPath.setNamespaceContext(new XFDLNamespaceContext()); Node result = (Node)xPath.evaluate(QUERY_FORM_NUMBER, doc, XPathConstants.NODE); if(result != null) { return result.getNodeValue(); } else { throw new InvalidFormException("Unable to identify form."); } } catch (XPathExpressionException err) { throw new InvalidFormException("Unable to find form number in file."); } }
Where QUERY_FORM_NUMBER is an XPath expression, and XFDLNamespaceContext implements NamespaceContext and looks like this:
public class XFDLNamespaceContext implements NamespaceContext { @Override public String getNamespaceURI(String prefix) { if (prefix == null) throw new NullPointerException("Invalid Namespace Prefix"); else if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) return "http://www.PureEdge.com/XFDL/6.5"; else if ("custom".equals(prefix)) return "http://www.PureEdge.com/XFDL/Custom"; else if ("designer".equals(prefix)) return "http://www.PureEdge.com/Designer/6.1"; else if ("pecs".equals(prefix)) return "http://www.PureEdge.com/PECustomerService"; else if ("xfdl".equals(prefix)) return "http://www.PureEdge.com/XFDL/6.5"; else if ("xforms".equals(prefix)) return "http://www.w3.org/2003/xforms"; else return XMLConstants.NULL_NS_URI; } @Override public String getPrefix(String arg0) {
I have tried many different XPath queries, but I feel this should work:
protected static final String QUERY_FORM_NUMBER = "/globalpage/global/xmlmodel/xforms:instances/instance" + "/form_metadata/title/documentnbr[number]";
Unfortunately, this does not work, and I constantly get zero returns.
I did quite a bit of reading here , here , and here , but nothing turned out to be light enough to help me get this work.
I am pretty sure that I will palm off when I find out about it, but I really am on the verge of what is missing.
Thank you for reading all this and in advance for your help.
-Andy