坚持使用java XPath

时间:2014-12-11 12:37:51

标签: java xml xpath

有人可以找到此代码的错误。无论我选择哪种XPath,它总是返回空字符串

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("chart.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
String str = (String) xpath.evaluate("/row[@id='1']", doc.getDocumentElement(),    XPathConstants.STRING);
System.out.println("xml string is"+str);

我的chart.xml是

<?xml version="1.0" encoding="iso-8859-1"?>
 <chart>
  <row id="1">
    <Select numofobjects="0" id="1000" index="1">
      <Table alias="ConvertDetails" name="ConvertDetails"/>
   </Select>
 </row>
 <row id="2">
   <Select numofobjects="0" id="2000" index="2">
      <Table alias="ConvertDetails" name="ConvertDetails"/>
  </Select>
 </row>
</chart>

我的预期输出是

<Select numofobjects="0" id="1000" index="1">
      <Table alias="ConvertDetails" name="ConvertDetails"/>
   </Select>

3 个答案:

答案 0 :(得分:2)

正如Martin指出的那样,你需要选择一个节点,而不是它的字符串值:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("chart.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
Node n = (Node) xpath.evaluate("row[@id='1']", doc.getDocumentElement(), 
                               XPathConstants.NODE);

然后您可以使用以下序列化帮助方法(借鉴Get a node's inner XML as String in Java DOM):

public static String innerXml(Node node) {
    DOMImplementationLS lsImpl = (DOMImplementationLS)node.getOwnerDocument()
                                                          .getImplementation()
                                                          .getFeature("LS", "3.0");
    LSSerializer lsSerializer = lsImpl.createLSSerializer();
    lsSerializer.getDomConfig().setParameter("xml-declaration", false);
    NodeList childNodes = node.getChildNodes();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < childNodes.getLength(); i++) {
       sb.append(lsSerializer.writeToString(childNodes.item(i)));
    }
    return sb.toString(); 
}

像这样:

String xmlStr = "";
if (n != null) {
    xmlStr = innerXml(node);
}

答案 1 :(得分:0)

如果要选择节点,请不要使用XPathConstants.STRING,因为它会获取所选节点的字符串内容,并且所有元素都为空。您需要选择节点或节点集,并确保在需要其标记时序列化节点。

答案 2 :(得分:0)

使用@ JLRishe的代码完美无缺(+1)。

问题在于您的XML文档。您关闭了<Select>代码错误(使用</SelectOne> \ </SelectTwo>)。

尝试在以下XML上运行此代码:

<强>代码:

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

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;

public class XMLSerializer {
    public static void main(String[] args) {
        try {
            DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
            domFactory.setNamespaceAware(true);
            DocumentBuilder builder = domFactory.newDocumentBuilder();
            Document doc = builder.parse("chart.xml");
            XPath xpath = XPathFactory.newInstance().newXPath();
            Node n = (Node) xpath.evaluate("row[@id='1']", doc.getDocumentElement(), 
                                           XPathConstants.NODE);

            String xmlStr = "";
            if (n != null) {
                xmlStr = innerXml(n);
                System.out.println("xml string is"+xmlStr);
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static String innerXml(Node node) {
        DOMImplementationLS lsImpl = (DOMImplementationLS)node.getOwnerDocument()
                                                              .getImplementation()
                                                              .getFeature("LS", "3.0");
        LSSerializer lsSerializer = lsImpl.createLSSerializer();
        lsSerializer.getDomConfig().setParameter("xml-declaration", false);
        NodeList childNodes = node.getChildNodes();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < childNodes.getLength(); i++) {
           sb.append(lsSerializer.writeToString(childNodes.item(i)));
        }
        return sb.toString(); 
    }
}

<强> XML:

<?xml version="1.0" encoding="iso-8859-1"?>
<chart>
  <row id="1">
    <Select numofobjects="0" id="1000" index="1">
      <Table alias="ConvertDetails" name="ConvertDetails"/>
    </Select>
  </row>
  <row id="2">
    <Select numofobjects="0" id="2000" index="2">
      <Table alias="ConvertDetails" name="ConvertDetails"/>
    </Select>
  </row>
</chart>