Reputation: 18572
I have to parse xml file with xsd validation.
It throws java.lang.NullPointerException
:
Exception in thread "main" java.lang.NullPointerException
content Carl Cracker
at com.epam.lab.DomXmlParser.parseFromXmlToEmployee(DomParserDemo.java:103)
content 75000
at com.epam.lab.DomParserDemo.main(DomParserDemo.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Here is content of xml file:
<?xml version="1.0" encoding="UTF-8"?>
<staff xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="newEmployee.xsd">
<employee>
<name>Carl Cracker</name>
<salary>75000</salary>
<hiredate year="1987" month="12" day="15" />
</employee>
<employee>
<name>Harry Hacker</name>
<salary>50000</salary>
<hiredate year="1989" month="10" day="1" />
</employee>
<employee>
<name>Tony Tester</name>
<salary>40000</salary>
<hiredate year="1990" month="3" day="15" />
</employee>
</staff>
And code snippet:
class DomXmlParser {
private Schema schema;
private Document document;
List<Employee> empList = new ArrayList<>();
public SchemaFactory schemaFactory;
public final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
public final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
public DomXmlParser() { // String filename, String schemaName - param
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(new File(EMPLOYEE_XML.getFilename()));
} catch (Exception e) {
e.printStackTrace();
}
}
public List<Employee> parseFromXmlToEmployee() {
NodeList nodeList = document.getDocumentElement().getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof Element) {
Employee emp = new Employee();
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
Node cNode = childNodes.item(j);
// identify the child tag of employees
if (cNode instanceof Element) {
String content = cNode.getLastChild().getTextContent().trim();
if (content.length() == 0) break;
System.out.println("content " + content);
switch (cNode.getNodeName()) {
case "name":
emp.setName(content);
break;
case "salary":
emp.setSalary(Double.parseDouble(content));
break;
case "hiredate":
int yearAttr = Integer.parseInt(cNode.getAttributes().getNamedItem("year").getNodeValue());
int monthAttr = Integer.parseInt(cNode.getAttributes().getNamedItem("month").getNodeValue());
int dayAttr = Integer.parseInt(cNode.getAttributes().getNamedItem("day").getNodeValue());
emp.setHireDay(yearAttr, monthAttr - 1, dayAttr);
break;
}
}
}
empList.add(emp);
}
}
return empList;
}
}
I understand that I'm trying extract attribute from empty element, but I can't find any circumvent.
How to solve this trouble?
Upvotes: 1
Views: 1312
Reputation: 108859
You can replace the null with an empty string when the node has no children:
String content = (cNode.hasChildNodes())
? cNode.getTextContent().trim()
: "";
if (content.length() == 0) break;
However, would be better to only read the content when it makes sense to do so:
// remove content variable
emp.setName(text(cNode));
// ... later ...
private String text(Node cNode) {
return cNode.getTextContent()
.trim();
}
Note that it is redundant to get the Text node by calling getLastChild() when using getTextContent() on an Element.
Upvotes: 2