Ercument Kisa
Ercument Kisa

Reputation: 168

Java SAX Parser Namespace Throws NullPointerException

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

Answers (1)

zaerymoghaddam
zaerymoghaddam

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

Related Questions