0

I'm trying to extract data from a XML file via XPath. My code works on a XML without namespaces, but as mine has a namespace I added the necessary NamespaceContext to the X Path object. Unfortunately the XPath didn't deliver any data, so after some fiddling around I ended up with my code unchanged but this jar xmlparserv2.jar added to the class-path. And voila, all of a sudden everything works perfectly.

I can see that the jar contains classes which are already in the JDK(1.7.0_15) but probably a different version.

So my questions are

a) Is there a way to find out what's going wrong with the original classes from the JDK besides from me having to debug through endless classes?

b) Has anybody an idea for an alternative solution/how I could change my code so that I don't have to ship an additional "unnecessary" jar?

Thanks Simon

That's the code in question:

public class JavaApplication1 {

public static void main(String[] args) throws IOException, SAXException {
    Document doc = createDoc("Persons.xml");
    parseSFMessage(doc);
}

private static void parseSFMessage(Node node) {
    if (node.getNodeName().startsWith("Persons:person") && node.hasChildNodes()) {
        print("PLZ: " + getNodeValue(node, "ns1:PLZ"));
    }
    NodeList nodeList = node.getChildNodes();
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node currentNode = nodeList.item(i);
        if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
            parseSFMessage(currentNode);
        }
    }
}

private static Document createDoc(String s) {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = null;
    Document doc = null;
    try {
        builder = factory.newDocumentBuilder();
        doc = builder.parse(new FileInputStream(s));
    } catch (SAXException e) {
    } catch (IOException e) {
    } catch (ParserConfigurationException e) {
    }
    return doc;
}

private static String getNodeValue(Node dom, String element) {
    NamespaceContext ctx = new NamespaceContext() {
        public String getNamespaceURI(String prefix) {
            String uri;
            if (prefix.equals("ns1")) {
                uri = "http://someurl.com/schemas/class/Utils";
            } else {
                uri = null;
            }
            return uri;
        }
        public Iterator getPrefixes(String val) {
            return null;
        }
        public String getPrefix(String uri) {
            return null;
        }
    };
    String result = null;
    XPathFactory xpf = XPathFactory.newInstance();
    XPath xp = xpf.newXPath();
    xp.setNamespaceContext(ctx);
    try {
        result = xp.evaluate(element, dom);
    } catch (XPathExpressionException e) {
        e.printStackTrace();
    }
    return result;
}

private static void print(Object o) {
    if (o != null) {
        System.out.println(o.toString());
    }
}
}
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
schnesim
  • 441
  • 1
  • 3
  • 17
  • This might be helpful - http://stackoverflow.com/questions/914013/namespacecontext-and-using-namespaces-with-xpath. – Perception Feb 23 '13 at 15:46

1 Answers1

1

You need to note that DocumentBuilderFactory is not namespace aware by default. You must call factory.setNamespaceAware(true); before you do factory.newDocumentBuilder() in order to get a builder that will parse the XML properly with namespace support.

As for why it worked with xmlparserv2 I can only speculate that maybe that particular parser goes against the JAXP spec and enables namespaces by default.

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183