0

How to handle null XML tags using java XPATH ?

 <?xml version="1.0" encoding="UTF-8"?>
 <Employees>    
 <Employee emplid="1111" type="admin">    
 **<firstname/>**  
 <lastname>Watson</lastname>         
 <age>30</age>         
 <email>[email protected]</email>     
 </Employee>     
 <Employee emplid="2222" type="admin">         
 <firstname>Sherlock</firstname>         
 <lastname>Homes</lastname>         
 <age>32</age>         
 <email>[email protected]</email>     
 </Employee>
 </Employees> 

In the above the XML <firstname/> tag is empty, how can I display default value without throwing exception?

Currently using:

System.out.println("*************************"); 

expression = "/Employees/Employee/firstname"; 

System.out.println(expression); 

NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, 
XPathConstants.NODESET);

for (int i = 0; i < nodeList.getLength(); i++) {                 

    System.out.println(nodeList.item(i).getFirstChild().getNodeValue());              

}
0

2 Answers 2

2

There is no such thing as a "null tag". I think you mean an "empty element". You'll find it easier to find the answers to such questions if you learn to use the correct jargon.

The simplest solution is to use an XPath expression that returns the string value of the node, rather than the node itself. Try to follow the principle of doing as much as possible in XPath, and as little as possible in Java, because XPath is custom-designed for processing XML, and Java isn't.

(Ideally, don't process your data in Java at all: do it all in XML-based languages such as XPath, XSLT and XQuery).

You can get the string value of the first employee using the expression string(/Employees/Employee[1]/firstname)

Sign up to request clarification or add additional context in comments.

Comments

2

Running this Java program demonstrating the use of XPaths to obtain possibly empty element contents:

import java.io.StringReader;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import org.xml.sax.InputSource;
import java.util.Arrays;
import java.util.List;

public class Try {
    public static void main(String[] args) throws Exception {
        String xml =
          "<?xml version='1.0' encoding='UTF-8'?>"
          + "<Employees>"
          + "  <Employee emplid='1111' type='admin'>"
          + "    <firstname/>"
          + "    <lastname>Watson</lastname>"
          + "    <age>30</age>"
          + "    <email>[email protected]</email>"
          + "  </Employee>"
          + "  <Employee emplid='2222' type='admin'>"
          + "    <firstname>Sherlock</firstname>"
          + "    <lastname>Homes</lastname>"
          + "    <age>32</age>"
          + "    <email>[email protected]</email>"
          + "  </Employee>"
          + "</Employees>";
        List<String> ids = Arrays.asList("1111", "2222");
        for(int i = 0; i < ids.size(); i++) {
          String employeeId = ids.get(i);
          String xpath = "/Employees/Employee[@emplid='" + employeeId + "']/firstname";
          XPath xPath = XPathFactory.newInstance().newXPath();
          String employeeFirstName = xPath.evaluate(xpath, new InputSource(new StringReader(xml)));
          if (employeeFirstName == "") {
            System.out.println("Employee " + employeeId +  " has no first name.");
          } else {
            System.out.println("Employee " + employeeId + "'s first name is " + employeeFirstName);
          }
        }
    }
}

Will produce this output:

Employee 1111 has no first name.
Employee 2222's first name is Sherlock

Update per OP's request in comments

Running this Java program correcting OP's NodeList processing:

import java.io.StringReader;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.xml.sax.InputSource;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;

public class Try {
    public static void main(String[] args) throws Exception {
        String xml =
          "<?xml version='1.0' encoding='UTF-8'?>"
          + "<Employees>"
          + "  <Employee emplid='1111' type='admin'>"
          + "    <firstname/>"
          + "    <lastname>Watson</lastname>"
          + "    <age>30</age>"
          + "    <email>[email protected]</email>"
          + "  </Employee>"
          + "  <Employee emplid='2222' type='admin'>"
          + "    <firstname>Sherlock</firstname>"
          + "    <lastname>Homes</lastname>"
          + "    <age>32</age>"
          + "    <email>[email protected]</email>"
          + "  </Employee>"
          + "</Employees>";
        System.out.println("*************************");
        String expression = "/Employees/Employee/firstname";
        System.out.println(expression);
        XPath xPath = XPathFactory.newInstance().newXPath();
        NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(new InputSource(new StringReader(xml)),
                                                                          XPathConstants.NODESET);
        for (int i = 0; i < nodeList.getLength(); i++) {
          if (nodeList.item(i).getFirstChild() == null)
            System.out.println("Employee has no first name.");
          else
            System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
        }
    }
}

Will produce this output:

/Employees/Employee/firstname
Employee has no first name.
Sherlock

1 Comment

I have added working code that incorporates your code snippet. In return, I ask that you please accept some answer to this question and also answers to your previous questions that have helped you. You've gotten good answers in the past; you should thank those who've taken time to help by voting up and accepting appropriate answers. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.