如何使用java XPATH处理空XML标记?

时间:2013-12-10 04:08:15

标签: java xml dom xpath sax

如何使用java XPATH处理空XML标记?

 <?xml version="1.0" encoding="UTF-8"?>
 <Employees>    
 <Employee emplid="1111" type="admin">    
 **<firstname/>**  
 <lastname>Watson</lastname>         
 <age>30</age>         
 <email>johnwatson@sh.com</email>     
 </Employee>     
 <Employee emplid="2222" type="admin">         
 <firstname>Sherlock</firstname>         
 <lastname>Homes</lastname>         
 <age>32</age>         
 <email>sherlock@sh.com</email>     
 </Employee>
 </Employees> 

在上面,XML <firstname/>标记为空,如何在不抛出异常的情况下显示默认值?

目前正在使用:

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());              

}

2 个答案:

答案 0 :(得分:2)

运行此Java程序演示如何使用XPath获取可能为空的元素内容:

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>johnwatson@sh.com</email>"
          + "  </Employee>"
          + "  <Employee emplid='2222' type='admin'>"
          + "    <firstname>Sherlock</firstname>"
          + "    <lastname>Homes</lastname>"
          + "    <age>32</age>"
          + "    <email>sherlock@sh.com</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);
          }
        }
    }
}

会产生此输出:

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

在评论中更新每个OP的请求

运行此Java程序纠正OP的NodeList处理:

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>johnwatson@sh.com</email>"
          + "  </Employee>"
          + "  <Employee emplid='2222' type='admin'>"
          + "    <firstname>Sherlock</firstname>"
          + "    <lastname>Homes</lastname>"
          + "    <age>32</age>"
          + "    <email>sherlock@sh.com</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());
        }
    }
}

会产生此输出:

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

答案 1 :(得分:2)

没有“null标签”这样的东西。我认为你的意思是“空元素”。如果你学会使用正确的术语,你会发现找到这些问题的答案会更容易。

最简单的解决方案是使用XPath表达式返回节点的字符串值,而不是节点本身。尝试遵循在XPath中尽可能多地执行的原则,并尽可能少地在Java中执行,因为XPath是为处理XML而定制设计的,而Java则不是。

(理想情况下,根本不要用Java处理数据:在基于XML的语言中完成所有操作,例如XPath,XSLT和XQuery)。

您可以使用表达式string(/Employees/Employee[1]/firstname)

获取第一位员工的字符串值