Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPath not working properly when the root tag got xmlns property

Tags:

java

xml

xpath

I'm trying to parse an xml file using XPath

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    domFactory.setNamespaceAware(true); // never forget this!
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse(File);

    XPathFactory factory = XPathFactory.newInstance();
    XPath xpath = factory.newXPath();
    XPathExpression expr 
     = xpath.compile("//PerosnList/List/Person");

It took me alot of time to see that it's not working cause the root element got xmlns attribute once i remove the attr it works fine!, how can i workaround this xlmns attr without deleting it from the file ?

The xml looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/vsDal.Entities">
.....
....
<PersonList>
...
<List>
<Person></Person>
<Person></Person>
<Person></Person>
</List>
</PersonList>
</Root>

Thanks.

like image 761
ibm123 Avatar asked Feb 20 '12 10:02

ibm123


2 Answers

The xmlns attribute is more than just a regular attribute. It is a namespace attribute which are used to uniquely qualify elements and attributes.

The PersonList, List, and Person elements "inherit" that namespace. Your XPath isn't matching because you are selecting elements in the "no namespace". In order to address elements bound to a namespace in XPath 1.0 you must define a namespace-prefix and use it in your XPath expression.

You could make your XPath more generic and just match on the local-name, so that it matches the elements regardless of their namespace:

//*[local-name()='PersonList']/*[local-name()='List']/*[local-name()='Person']
like image 71
Mads Hansen Avatar answered Nov 15 '22 00:11

Mads Hansen


You need to provide a NamespaceContext and namespace your expression. See here for an example.

like image 21
McDowell Avatar answered Nov 15 '22 01:11

McDowell