Reputation: 168
I want to parse an XML document by using SAX Parser. When the document does not contain any namespace, it works perfectly. However, when I add namespaces to the root element, I am facing with a NullPointerException.
Here is my working XML document:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Date>01102013</Date>
<ID>1</ID>
<Count>3</Count>
<Items>
<Item>
<Date>01102013</Date>
<Amount>100</Amount>
</Item>
<Item>
<Date>02102013</Date>
<Amount>200</Amount>
</Item>
</Items>
</Root>
This is the problematic version:
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.xyz.com/q">
<Date>01102013</Date>
<ID>1</ID>
<Count>3</Count>
<Items>
<Item>
<Date>01102013</Date>
<Amount>100</Amount>
</Item>
<Item>
<Date>02102013</Date>
<Amount>200</Amount>
</Item>
</Items>
</Root>
Here is my code:
Document doc = null;
SAXBuilder sax = new SAXBuilder();
sax.setFeature("http://xml.org/sax/features/external-general-entities", false);
// I set this as true but still nothing changes
sax.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
sax.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
doc = sax.build(xmlFile); // xmlFile is a File object which is a function parameter
Root root = new Root();
Element element = doc.getRootElement();
root.setDate(element.getChild("Date").getValue());
root.setID(element.getChild("ID").getValue());
.
.
.
When I use the first XML, it is working fine. When I use the second XML
element.getChild("Date").getValue()
returns null.
Note: I can read the "http://www.xyz.com/q" part by using
doc.getRootElement().getNamespaceURI();
which means I can still access the root element.
Anyone have an idea how to overcome this?
Thanks in advance.
Upvotes: 2
Views: 751
Reputation: 3127
You can use multiple namespaces in a XML document and each element can have each own namespace. In order to access document elements in a normal document (without namespaces) you can use methods like getChild
or getAttribute
which has just one argument that is the child name or attribute name. This is what you have used in your code.
But in order to access the namespaced version, you have to use another override of these methods which have a second parameter of type Namespace
. This way, you can query an element for its child or attribute base on given namespace. So if you want to read your second document (which has namespaces) your code would be something like this:
// The first parameter is the prefix of this namespace in your document. in your sample it's an empty string
Namespace ns = Namespace.getNamespace("", "http://www.xyz.com/q");
Element element = doc.getRootElement();
root.setDate(element.getChild("Date", ns).getValue());
root.setID(element.getChild("ID", ns).getValue());
Upvotes: 1