坚持使用JavaXPath

坚持使用JavaXPath,java,xml,xpath,Java,Xml,Xpath,有人能找出这个代码的错误吗。无论我选择什么XPath,它总是返回空字符串 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse("chart.xml"); X

有人能找出这个代码的错误吗。无论我选择什么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>


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

正如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);
然后可以使用以下序列化帮助器方法(借用自):


使用@JLRishe的代码可以完美地工作(+1)

问题在于您的XML文档。您错误地关闭了
标记(使用
\

请尝试在以下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 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>
import javax.xml.parsers.DocumentBuilder;
导入javax.xml.parsers.DocumentBuilderFactory;
导入javax.xml.xpath.xpath;
导入javax.xml.xpath.XPathConstants;
导入javax.xml.xpath.XPathFactory;
导入org.w3c.dom.Document;
导入org.w3c.dom.Node;
导入org.w3c.dom.NodeList;
导入org.w3c.dom.ls.dom实现;
导入org.w3c.dom.ls.LSSerializer;
公共类XMLSerializer{
公共静态void main(字符串[]args){
试一试{
DocumentBuilderFactory domFactory=DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder=domFactory.newDocumentBuilder();
documentdoc=builder.parse(“chart.xml”);
XPath=XPathFactory.newInstance().newXPath();
Node n=(Node)xpath.evaluate(“row[@id='1']”,doc.getDocumentElement(),
XPathConstants.NODE);
字符串xmlStr=“”;
如果(n!=null){
xmlStr=innerXml(n);
System.out.println(“xml字符串是”+xmlStr);
}
}捕获(例外情况除外){
例如printStackTrace();
}
}
公共静态字符串innerXml(节点){
domImplementals lsImpl=(domImplementals)节点。getOwnerDocument()
.getImplementation()
.getFeature(“LS”、“3.0”);
LSSerializer LSSerializer=lsImpl.createLSSerializer();
lsSerializer.getDomConfig().setParameter(“xml声明”,false);
NodeList childNodes=node.getChildNodes();
StringBuilder sb=新的StringBuilder();
对于(int i=0;i
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 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>


我尝试了这两种方法,但它总是只返回null。如果我错了,请纠正我。代码:-节点节点=(节点)xpath.evaluate(“/row[@id='1']”,doc.getDocumentElement(),XPathConstants.Node);路径也是错误的,为了使选择相对于文档元素(即
图表
元素)有意义,请使用
行[@id=1]
。JLRishe我在执行上述代码“org.w3c.dom.ls.LSException:无法序列化节点:无法序列化节点:无法序列化节点”时遇到此异常,我不确定是什么原因造成的。哪一行产生错误?sb.append(lsSerializer.writeToString(childNodes.item(i));它在独立程序中工作良好。如果我在apache服务器中使用它,它将抛出org.w3c.dom.ls.LSException异常。您确定XML格式正确吗?您可以在处理文档之前对其进行验证。