Reputation: 1013
I want to loop through all elements in a piece of XML printing each one. My problem is that I keep getting a null pointer exception after the staff1
tag, i.e. john 465456433 gmail1 area1 city1
This my Java code to print all elements in an xml file:
File fXmlFile = new File("file.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("*");
System.out.println("----------------------------");
Node n=null;
Element eElement=null;
for (int i = 0; i < nList.getLength(); i++) {
System.out.println(nList.getLength());
n= nList.item(i);
System.out.println("\nCurrent Element :" + n.getNodeName());
if (n.getNodeType() == Node.ELEMENT_NODE) {
eElement = (Element) n.getChildNodes();
System.out.println("\nCurrent Element :" + n.getNodeName());
name = eElement.getElementsByTagName("name").item(i).getTextContent(); //here throws null pointer exception after printing staff1 tag
phone = eElement.getElementsByTagName("phone").item(i).getTextContent();
email = eElement.getElementsByTagName("email").item(i).getTextContent();
area = eElement.getElementsByTagName("area").item(i).getTextContent();
city = eElement.getElementsByTagName("city").item(i).getTextContent();
}
n.getNextSibling();
}
XML File:
<?xml version="1.0"?>
<company>
<staff1>
<name>john</name>
<phone>465456433</phone>
<email>gmail1</email>
<area>area1</area>
<city>city1</city>
</staff1>
<staff2>
<name>mary</name>
<phone>4655556433</phone>
<email>gmail2</email>
<area>area2</area>
<city>city2</city>
</staff2>
<staff3>
<name>furvi</name>
<phone>4655433</phone>
<email>gmail3</email>
<area>area3</area>
<city>city3</city>
</staff3>
</company>
Expected Output:
john
465456433
gmail1
area1
city1
mary
4655556433
gmail2
area2
city2
furvi
4655433
gmail3
area3
city3
Upvotes: 40
Views: 188779
Reputation: 11
NodeList listaHijos = docEle.getChildNodes();
listaHijos = listaHijos.item(2).getChildNodes();
for (int i = 0; i < listaHijos.getLength(); i++) {
eElement = (Element) listaHijos.item(i);
n2 = eElement.getChildNodes();
for (int j = 0; j < n2.getLength(); j++) {
System.out.println("elem:" + n2.item(j).getNodeName() + " :" + n2.item(j).getTextContent() + "j" + j);
if (n2.item(j).getNodeName().equals("detallesAdicionales")) {
eElement = (Element) n2.item(j);
n6 = eElement.getChildNodes();
System.out.println("todo: " + n6.item(0).getAttributes().item(0) + n6.item(0).getAttributes().item(1));
System.out.println("todo2: " + n6.item(1).getAttributes().item(0) + n6.item(1).getAttributes().item(1));
System.out.println("todo3: " + n6.item(2).getAttributes().item(0) + n6.item(2).getAttributes().item(1));
System.out.println("nombre: " + n6.item(0).getAttributes().item(0).getTextContent());
System.out.println("valor: " + n6.item(0).getAttributes().item(1).getTextContent());
}
}
}
Upvotes: 1
Reputation: 6075
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse("file.xml");
Element docEle = dom.getDocumentElement();
NodeList nl = docEle.getChildNodes();
int length = nl.getLength();
for (int i = 0; i < length; i++) {
if (nl.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element el = (Element) nl.item(i);
if (el.getNodeName().contains("staff")) {
String name = el.getElementsByTagName("name").item(0).getTextContent();
String phone = el.getElementsByTagName("phone").item(0).getTextContent();
String email = el.getElementsByTagName("email").item(0).getTextContent();
String area = el.getElementsByTagName("area").item(0).getTextContent();
String city = el.getElementsByTagName("city").item(0).getTextContent();
}
}
}
Iterate over all children and nl.item(i).getNodeType() == Node.ELEMENT_NODE
is used to filter text nodes out. If there is nothing else in XML what remains are staff nodes.
For each node under stuff (name, phone, email, area, city)
el.getElementsByTagName("name").item(0).getTextContent();
el.getElementsByTagName("name")
will extract the "name" nodes under stuff,
.item(0)
will get you the first node
and .getTextContent()
will get the text content inside.
Edit: Since we have jackson I would do this in a different way. Define a pojo for the object:
public class Staff {
private String name;
private String phone;
private String email;
private String area;
private String city;
...getters setters
}
Then using jackson:
JsonNode root = new XmlMapper().readTree(xml.getBytes());
ObjectMapper mapper = new ObjectMapper();
root.forEach(node -> consume(node, mapper));
private void consume(JsonNode node, ObjectMapper mapper) {
try {
Staff staff = mapper.treeToValue(node, Staff.class);
//TODO your job with staff
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
Upvotes: 80
Reputation: 39
Here is another way to loop through XML elements using JDOM.
List<Element> nodeNodes = inputNode.getChildren();
if (nodeNodes != null) {
for (Element nodeNode : nodeNodes) {
List<Element> elements = nodeNode.getChildren(elementName);
if (elements != null) {
elements.size();
nodeNodes.removeAll(elements);
}
}
Upvotes: 3
Reputation: 503
public class XMLParser {
public static void main(String[] args){
try {
DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = dBuilder.parse(new File("xml input"));
NodeList nl=doc.getDocumentElement().getChildNodes();
for(int k=0;k<nl.getLength();k++){
printTags((Node)nl.item(k));
}
} catch (Exception e) {/*err handling*/}
}
public static void printTags(Node nodes){
if(nodes.hasChildNodes() || nodes.getNodeType()!=3){
System.out.println(nodes.getNodeName()+" : "+nodes.getTextContent());
NodeList nl=nodes.getChildNodes();
for(int j=0;j<nl.getLength();j++)printTags(nl.item(j));
}
}
}
Recursively loop through and print out all the xml child tags in the document, in case you don't have to change the code to handle dynamic changes in xml, provided it's a well formed xml.
Upvotes: 9