2013-03-28 132 views
0

这是使用Java中的XPath解析XML的以下标准代码。我无法调试为什么我得到空值。我附加了java文件,xml文件和输出。如果有人能够解释我在哪里出错,我将不胜感激。提前致谢! :)Java中的XML XPath解析

XPathParser.java

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathConstants; 
import javax.xml.xpath.XPathExpression; 
import javax.xml.xpath.XPathFactory; 

import org.w3c.dom.Document; 
import org.w3c.dom.NodeList; 

public class XPathParser { 
    public static void main(String args[]) throws Exception { 
     //loading the XML document from a file 
     DocumentBuilderFactory builderfactory = DocumentBuilderFactory.newInstance(); 
     builderfactory.setNamespaceAware(true); 

     //XML read 
     DocumentBuilder builder = builderfactory.newDocumentBuilder(); 
     Document xmlDocument = builder.parse("Stocks.xml"); 

     // Creates a XPath factory 
     XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance(); 

     //Creates a XPath Object 
     XPath xPath = factory.newXPath(); 

     //Compiles the XPath expression 
     //XPathExpression xPathExpression_count = xPath.compile("count(//stock)"); 
     XPathExpression xPathExpression = xPath.compile("//stock"); 

     //Run the query and get a nodeset 
     Object result = xPathExpression.evaluate(xmlDocument,XPathConstants.NODESET); 

     //Cast the result into a DOM nodelist 
     NodeList nodes = (NodeList) result; 
     System.out.println(nodes.getLength()); 
     System.out.println(nodes.item(0)); 
     for (int i=0; i<nodes.getLength();i++){ 
      System.out.println(nodes.item(i).getNodeValue()); 
     } 
    } 
} 

Stocks.xml

<?xml version="1.0" encoding="UTF-8"?> 
<stocks> 
       <stock> 
              <symbol>ABC</symbol> 
              <price>10</price> 
              <quantity>50</quantity> 
       </stock> 
       <stock> 
              <symbol>XYZ</symbol> 
              <price>20</price> 
              <quantity>1000</quantity> 
       </stock> 
</stocks> 

OUTPUT:

2 
[stock: null] 
null 
null 
+1

你期待什么?你的XPath选择所有'stock'节点,然后调用['getNodeValue'](http://docs.oracle.com/javase/1.5.0/docs/api/org/w3c/dom/Node.html#getNodeValue( )),它们返回'null'。你想要得到什么? –

+1

尝试打印'nodes.item(i).getTextContent()'而不是'nodes.item(i).getNodeValue()'。或者将你的XPath表达式改为'// stock/text()' –

回答

0

您试图呼吁Stock节点getNodeValue方法 - 这不因为它们没有价值,所以它们是父节点。

你也可以遍历的Stock子节点,查找信息:

final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes())); 
final XPathExpression expression = XPathFactory.newInstance().newXPath().compile("//stock"); 
final NodeList nodeList = (NodeList) expression.evaluate(document, XPathConstants.NODESET); 
for (int i = 0; i < nodeList.getLength(); ++i) { 
    final NodeList childList = ((Element) nodeList.item(i)).getChildNodes(); 
    for (int j = 0; j < childList.getLength(); ++j) { 
     final Node node = childList.item(j); 
     if (node.getNodeType() == Node.ELEMENT_NODE) { 
      System.out.println(node.getNodeName() + "=" + node.getTextContent()); 
     } 
    } 
} 

输出:

symbol=ABC 
price=10 
quantity=50 
symbol=XYZ 
price=20 
quantity=1000 

注意,你必须按类型,否则过滤孩子Node是你遍历子节点和节点的文本值的组合,作为文本节点出现。这是通过这种方式浏览XML的常见问题。

你也可以遍历的Stock所有子文本节点:

final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes())); 
final XPathExpression expression = XPathFactory.newInstance().newXPath().compile("//stock/*/text()"); 
final NodeList nodeList = (NodeList) expression.evaluate(document, XPathConstants.NODESET); 
for (int i = 0; i < nodeList.getLength(); ++i) { 
    final Node node = nodeList.item(i); 
    System.out.println(node.getNodeValue()); 
} 

输出:

ABC 
10 
50 
XYZ 
20 
1000 

在这种情况下,你遍历所有文本节点是的Stock孩子们的孩子 - 这意味着你失去了有关节点名称的信息。但是你可以通过遍历的Stock所有儿童重新创建第一种方法是不文本节点:

final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes())); 
final XPathExpression expression = XPathFactory.newInstance().newXPath().compile("//stock/*"); 
final NodeList nodeList = (NodeList) expression.evaluate(document, XPathConstants.NODESET); 
for (int i = 0; i < nodeList.getLength(); ++i) { 
    final Node node = nodeList.item(i); 
    System.out.println(node.getNodeName() + "=" + node.getTextContent()); 
} 

输出:

symbol=ABC 
price=10 
quantity=50 
symbol=XYZ 
price=20 
quantity=1000 

或者,如果你愿意,你可以在XPath选择特定的子节点更具体的东西:

final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes())); 
final XPathExpression expression = XPathFactory.newInstance().newXPath().compile("//stock/symbol/text()"); 
final NodeList nodeList = (NodeList) expression.evaluate(document, XPathConstants.NODESET); 
for (int i = 0; i < nodeList.getLength(); ++i) { 
    final Node node = nodeList.item(i); 
    System.out.println(node.getNodeValue()); 
} 

输出:

ABC 
XYZ