XML DOM NullPointerException

dsNDesign

Erfahrenes Mitglied
Hei,
ich bin gerade dabei, eine XML Datei mithilfe von DOM zu parsen.

Ich habe folgende XML Datei + Schema:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<Kopierservice xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Kopierservice.xsd">
	<Benutzerkonto matrnr="12345">
		<Benutzer vorname="Vorname" name="Nachname">
			<Adresse typ="Privat">
				<Strasse>Strasse</Strasse>
				<PLZ>1234</PLZ>
				<Ort>Ort</Ort>
			</Adresse>
			<Adresse typ="Arbeit">
				<Strasse>Strasse 2</Strasse>
				<PLZ>23456</PLZ>
				<Ort>Ort2</Ort>
			</Adresse>
		</Benutzer>
		<Bestellungen>
			<Bestellung ZID="Z-1" AID="A-11" datum="2012-10-10" umfang="3" />
			<Bestellung ZID="Z-1" AID="A-13" datum="2012-10-10" umfang="1" />
		</Bestellungen>
	</Benutzerkonto>
	
	<Sortiment>
		<Zeitschrift ZID="Z-1"> 
			<Titel>Aalener Nachrichten</Titel>
			<Jahrgang>2009</Jahrgang>
			<Ausgabe>12</Ausgabe>
			<Aufsatz AID="A-11">
				<Ueberschrift>Wessl und die 7 Zwerge</Ueberschrift>
				<Autor>Patrick Christian Hieber</Autor>
				<Seitenanfang>1</Seitenanfang>
			</Aufsatz>
			<Aufsatz AID="A-12">
				<Ueberschrift>Wessl allein daheim</Ueberschrift>
				<Autor>Dila Schnee</Autor>
				<Seitenanfang>4</Seitenanfang>
			</Aufsatz>
			<Aufsatz AID="A-13">
				<Ueberschrift>Wessl for President</Ueberschrift>
				<Autor>Angela Merkel</Autor>
				<Seitenanfang>12</Seitenanfang>
			</Aufsatz>
		</Zeitschrift>	
	</Sortiment>	
</Kopierservice>

XML:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

	<xsd:element name="Kopierservice" type="KopierserviceType" />

	<xsd:complexType name="KopierserviceType">
		<xsd:sequence>
			<xsd:element name="Benutzerkonto" type="BenutzerkontoType" minOccurs="1" maxOccurs="unbounded" />
			<xsd:element name="Sortiment" type="SortimentType" />
		</xsd:sequence>
	</xsd:complexType>
	
	<xsd:complexType name="BenutzerkontoType">
		<xsd:sequence>
			<xsd:element name="Benutzer" type="BenutzerType" />
			<xsd:element name="Bestellungen" type="BestellungenType" />
		</xsd:sequence>
		<xsd:attribute name="matrnr" type="xsd:string" use="required" />
	</xsd:complexType>
	
	<xsd:complexType name="BenutzerType">
		<xsd:sequence>
			<xsd:element name="Adresse" type="AdresseType" minOccurs="1" maxOccurs="unbounded" />
		</xsd:sequence>
		<xsd:attribute name="vorname" type="xsd:string" use="required" />
		<xsd:attribute name="name" type="xsd:string" use="required" />
	</xsd:complexType>
	
	<xsd:complexType name="AdresseType">
		<xsd:sequence>
			<xsd:element name="Strasse" type="xsd:string" />
			<xsd:element name="PLZ" type="xsd:integer" />
			<xsd:element name="Ort" type="xsd:string" />
		</xsd:sequence>
		<xsd:attribute name="typ" type="xsd:string" use="required" />
	</xsd:complexType>
	
	<xsd:complexType name="BestellungenType">
		<xsd:sequence>
			<xsd:element name="Bestellung" type="BestellungType" minOccurs="0" maxOccurs="unbounded" />
		</xsd:sequence>
	</xsd:complexType>

	<xsd:complexType name="BestellungType">
		<xsd:attribute name="ZID" type="xsd:IDREF" use="required" />
		<xsd:attribute name="AID" type="xsd:IDREF" use="required" />
		<xsd:attribute name="datum" type="xsd:date" use="required" />
		<xsd:attribute name="umfang" type="xsd:integer" use="required" />
	</xsd:complexType>

	<xsd:complexType name="SortimentType">
		<xsd:sequence>
			<xsd:element name="Zeitschrift" type="ZeitschriftType" minOccurs="1" maxOccurs="unbounded" />
		</xsd:sequence>
	</xsd:complexType>
	
	<xsd:complexType name="ZeitschriftType">
		<xsd:sequence>
			<xsd:element name="Titel" type="xsd:string" />
			<xsd:element name="Jahrgang" type="xsd:integer" />
			<xsd:element name="Ausgabe" type="xsd:integer" />
			<xsd:element name="Aufsatz" type="AufsatzType" minOccurs="1" maxOccurs="unbounded" />
		</xsd:sequence>
		<xsd:attribute name="ZID" type="xsd:ID" use="required" />
	</xsd:complexType>

	<xsd:complexType name="AufsatzType">
		<xsd:sequence>
			<xsd:element name="Ueberschrift" type="xsd:string" />
			<xsd:element name="Autor" type="xsd:string" />
			<xsd:element name="Seitenanfang" type="xsd:integer" />
		</xsd:sequence>
		<xsd:attribute name="AID" type="xsd:ID" use="required" />
	</xsd:complexType>
</xsd:schema>

Dazu habe ich folgende Java-Datei:
Java:
import javax.xml.parsers.*;
import java.io.*;
import org.w3c.dom.*;
import org.xml.sax.*;

public class ZeitschriftDOM {
	private void outputAttributes(Node el) {
		Attr attr;
		NamedNodeMap attrMap = el.getAttributes();
		
		if(attrMap.getLength() > 0) {
			System.out.print("(");
			for(int i = 0; i < attrMap.getLength(); i++) {
				if(i > 0) {
					System.out.print(", ");
				}
				attr = (Attr) attrMap.item(i);
				System.out.print(attr.getName());
				System.out.print("=" + "\"" + attr.getValue() + "\"");
				if(attr.isId()) {
					System.out.print(" (ID)");
				}
			}
			System.out.print(")");
		}
	}
	
	private void outputContent2(Element el, int deep) {
		String str;
		Node child = el.getFirstChild();
		str = child.getNodeValue().trim();
		if(str.length() > 0) {
			System.out.println();
			for(int i = 0; i < (deep+1); i++) {
				System.out.print("  ");
			}
			System.out.print("\"" + str + "\"");
		}
	}
	
	private void outputConent(Element el, int deep) {
		Text text;
		String str;
		Node child = el.getFirstChild();
		
		if(child.getNodeType() == Node.TEXT_NODE) {
			text = (Text)child;
			str = text.getWholeText().trim();
			if(str.length() > 0) {
				System.out.println();
				for(int i = 0; i < (deep+1); i++) {
					System.out.print("  ");
				}
			System.out.print("\"" + str + "\"");
			}
		}
	}
	
	protected void outputEndOfElement() {
		System.out.println();
	}
	
	protected void outputElementName(String elName) {
		System.out.print(elName);
	}
	
	private void traverseRecursive(Element root, int deep) {
		NodeList nodeList;
		Node node;
		
		for(int i = 0; i < deep; i++) {
			System.out.print("  ");
		}
		
		outputElementName(root.getNodeName());
		outputAttributes(root);
		outputContent2(root, deep);
		outputEndOfElement();
		
		nodeList = root.getChildNodes();
		for(int i = 0; i < nodeList.getLength(); i++) {
			node = nodeList.item(i);
			if(node.getNodeType() == Node.ELEMENT_NODE) {
				traverseRecursive((Element) node, deep+1);
			}
		}
	}
	
	public void traverse(Document doc) {
		Node root = (Node)doc;
		NodeList nodeList;
		
		if(root.getNodeType() != Node.DOCUMENT_NODE) {
			System.out.println("Wurzelknoten ist kein Document-Element.");
			System.out.println("Sondern: " + root.getNodeType());
			System.out.println("Das Programm wird nun beendet.");
			System.exit(2);
			return;
		}
		nodeList = root.getChildNodes();
		for(int i = 0; i < nodeList.getLength(); i++) {
			root = nodeList.item(i);
			if(root.getNodeType() == Node.ELEMENT_NODE) {
				traverseRecursive((Element) root, 0);
			}
		}
	}
	
	public Document getXMLDocument(String xmlFile) {
		Document document = null;
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			
			factory.setIgnoringElementContentWhitespace(true);
			factory.setValidating(true);
			factory.setNamespaceAware(true);
			factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
			
			DocumentBuilder builder = factory.newDocumentBuilder();
			
			builder.setErrorHandler(new XMLErrorHandler());
			
			document = builder.parse(new File(xmlFile));
		} catch (SAXParseException e1) {
			System.err.println("Fehler (1)!");
			e1.printStackTrace();
		} catch (SAXException e2) {
			System.err.println("Fehler (2)!");
			e2.printStackTrace();
		} catch (ParserConfigurationException e3) {
			System.err.println("Fehler (3)!");
			e3.printStackTrace();
		} catch (IOException e4) {
			System.err.println("Fehler (4)!");
			e4.printStackTrace();
		}
		return document;
	}
	
	public static void main(String[] args) {
		if(args.length != 1) {
			System.out.println("Aufruf: java ZeitschriftSAX <Zeitschrift>");
			System.out.println("Das Programm wird nun beendet.");
			System.exit(1);
		}
		ZeitschriftDOM zeitschrift = new ZeitschriftDOM();
		zeitschrift.traverse(zeitschrift.getXMLDocument(args[0]));
	}
}

class XMLErrorHandler implements ErrorHandler {
	public void error(SAXParseException exception) {
		System.err.println("XML-Parse-Fehler!");
		exception.printStackTrace();
		System.out.println("Das Programm wird nun beendet.");
		System.exit(-1);
	}
	
	public void fatalError(SAXParseException exception) {
		System.err.println("XML-Parse-Fataler-Fehler!");
		exception.printStackTrace();
		System.out.println("Das Programm wird nun beendet.");
		System.exit(-2);
	}
	
	public void warning(SAXParseException exception) {
		System.err.println("XML-Parse-Warnung!");
		exception.printStackTrace();
		System.out.println("Das Programm wird nun beendet.");
		System.exit(-3);
	}
}

Zur Laufzeit erhalte ich jedoch folgenden Fehler:
java ZeitschriftDOM Kopierservice.xml
Kopierservice(xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance", xsi:noNamespaceSchemaLocation="Kopierservice.xsd")Exception in thread "main" java.lang.NullPointerException
at ZeitschriftDOM.outputContent2(ZeitschriftDOM.java:31)
at ZeitschriftDOM.traverseRecursive(ZeitschriftDOM.java:77)
at ZeitschriftDOM.traverse(ZeitschriftDOM.java:104)
at ZeitschriftDOM.main(ZeitschriftDOM.java:147)

Woran liegt das?

Gruß


EDIT:

Ich bin der Lösung inzwischen etwas näher.
Und zwar muss sich der Fehler in der Methode "outputContent" bzw "outputContent2" liegen. Diese rufe ich ja in der Zeile 77 auf.

Wenn ich dort die Methode outputContent2 aufrufe, kommt sofort der Fehler NullPointerException.

Wenn ich die Methode outputContent aufrufe, gibt er mir alles bis zur ersten "Bestelltung" aus. Also die erste Bestellung in der XML Datei wird noch ausgegeben, danach der Fehler.

Wenn ich den Aufruf der Methode komplett weg lasse, kommt kein Fehler und das Programm läuft ganz normal bis zum Ende.
Allerdings fehlt natürlich der Wert/Inhalt der Elemente
 
Zuletzt bearbeitet von einem Moderator:
Zurück