I'm trying to unmarshall a DOM node to an XML file using JAXB. However I keep receiving a NullPointerException. This only seems to occur when I create the DOM Node from scratch. The stack trace looks like the following:
java.lang.NullPointerException
at com.sun.xml.bind.unmarshaller.SAXUnmarshallerHandlerImpl.startElement
(SAXUnmarshallerHandlerImpl.java:87)
at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:109)
at com.sun.xml.bind.unmarshaller.DOMScanner.parse(DOMScanner.java:64)
at com.sun.xml.bind.unmarshaller.UnmarshallerImpl.unmarshal(Unmarshaller
Impl.java:149)
at Main.main(Main.java:103)
(If I unmarshal an XML file into a DOM node, I can successfully marshall the DOM node out to a new XML file using JAXB without error.)
Any insight into what I am doing wrong would be greatly appreciated!
Sample code and XSD follow...
Sample Code:
import itemlistsample.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
public class Main
{
public static void main(String[] args)
{
try
{
JAXBContext jc = JAXBContext.newInstance( "itemlistsample" );
Unmarshaller u = jc.createUnmarshaller();
/*
* Set up DOM Node Document Object.
*/
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
System.out.println();
System.out.println();
System.out.println("Create a DOM Node and unmarshall to an XML file");
/*
* Generate elements within DOM document
*/
Element itemListElt = (Element)doc.createElement("item_list");
Element itemInfo = (Element)doc.createElement("item_info");
Element name = (Element)doc.createElement("name");
Element price = (Element)doc.createElement("price");
/*
* 3-Ring Binder @ 4.99
*/
name.appendChild(doc.createTextNode("3-Ring Binder"));
itemInfo.appendChild(name);
price.appendChild(doc.createTextNode("4.99"));
itemInfo.appendChild(price);
itemListElt.appendChild(itemInfo);
/*
* Large Paper Clips @ 1.23
*/
itemInfo = (Element)doc.createElement("item_info");
name = (Element)doc.createElement("name");
price = (Element)doc.createElement("price");
name.appendChild(doc.createTextNode("Large Paper Clips"));
itemInfo.appendChild(name);
price.appendChild(doc.createTextNode("1.23"));
itemInfo.appendChild(price);
itemListElt.appendChild(itemInfo);
doc.appendChild(itemListElt);
/*
* Display DOM document as a sanity check
*/
itemListElt = doc.getDocumentElement();
System.out.println(itemListElt.getTagName());
NodeList nl = itemListElt.getElementsByTagName("item_info");
traverse(" ", nl.item(0));
/*
* Use JAXB to unmarshal the DOM document into
* an instance of the generated JAXB class for
* the root element. >>>Stack trace occurs here!<<<
*/
ItemListType il = (ItemListType)u.unmarshal(doc);
/*
* Marshal to an XML file
*/
Marshaller m = jc.createMarshaller();
m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
m.marshal( il, new FileOutputStream("item_new.xml") );
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void traverse(String indent, Node n)
{
if (n != null)
{
if (n.getNodeName() != null)
{
System.out.println(indent + n.getNodeName());
traverse(indent + " ", n.getFirstChild());
}
if (n.getNodeValue() != null)
{
System.out.println(indent + n.getNodeValue());
}
traverse(indent, n.getNextSibling());
}
}
}
Sample XSD:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsd:schema xmlns:xsd="
http://www.w3.org/2001/XMLSchema">
<xsd:element name="item_list" type="ItemListType"/>
<xsd:complexType name="ItemListType">
<xsd:sequence>
<xsd:element name="item_info" type="ItemInfoType" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ItemInfoType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="price" type="xsd:double"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>