我正在尝试将节点导入到新的' 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方法(或导入后采用)时,会看到相同的行为。
任何答案/解释/建议/意见表示赞赏。
答案 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);
}
}
}