Java xPath / DOM - 将节点导入文档时,xPath查询无法找到新节点(和子节点)

时间:2014-10-08 20:45:05

标签: java xml dom xpath

我正在尝试将节点导入到新的' DOM Document然后在新导入的节点上执行xPath查询。我正在使用的XML没有名称空间。我按照标准程序创建了一个文档,如下所示:

    Document newDoc = null;
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    try {
          DocumentBuilder builder = factory.newDocumentBuilder();
          newDoc = builder.newDocument();   
    } catch (ParserConfigurationException pce) {
      // Parser with specified options can't be built
      pce.printStackTrace();
    }

并导入节点......

    // nodeToImport is a node from a prior xPath search (part of a node set)
    Node docToRunXPathOn = newDoc.importNode(nodeToImport, true);

稍后,当我尝试运行xPath查询时,例如

    XPathFactory xPathFactory = XPathFactory.newInstance();
    XPath xpath = xPathFactory.newXPath();

    if (docToRunXPathOn != null) {
        try {
            XPathExpression expr = xpath.compile("//version_id/text()");
            return (String)expr.evaluate(doc, XPathConstants.STRING);
        } catch (XPathExpressionException e) {
            logger.error(e);
        }
    }

评估返回一个空字符串。下面是一个示例XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <Version>
       <version_id>51312</version_id>
       <description>Some Description</description>
    </Version>

我使用的解决方案是将DOM序列化为字符串,然后立即解析该字符串以将结构重新构建为新DOM。这似乎非常低效和倒退 - 我对这个导入和xPath缺少什么?我原以为可能是因为节点的父节点没有正确设置,但是当我执行clone / adopt方法(或导入后采用)时,会看到相同的行为。

任何答案/解释/建议/意见表示赞赏。

1 个答案:

答案 0 :(得分:0)

我写了一个小的testcase进行重现,导入后XPath发现“51312”,也许有帮助。

public class ImportNodeTest {
@Test
public void testImportNode() throws Exception {
    final Document newDocument = createDocument();
    final Element importedElement = getExistedNode();

    Node docToRunXPathOn = newDocument.importNode(importedElement, true);
    newDocument.appendChild(docToRunXPathOn);

    XPathFactory xPathFactory = XPathFactory.newInstance();
    XPath xpath = xPathFactory.newXPath();

    XPathExpression expr = xpath.compile("//version_id/text()");
    System.out.println(expr.evaluate(newDocument, XPathConstants.STRING));
}

private Document createDocument() {
    Document newDoc = null;
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    try {
        DocumentBuilder builder = factory.newDocumentBuilder();
        newDoc = builder.newDocument();
    } catch (ParserConfigurationException pce) {
        // Parser with specified options can't be built
        pce.printStackTrace();
    }
    return newDoc;
}


private Element getExistedNode() {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    try {
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File("xml.xml"));
        return document.getDocumentElement();
    } catch (Exception pce) {
        throw new RuntimeException(pce);
    }

}

}