我在项目中使用 XPATH,我需要有条件地遍历节点
public static String getNodeContentForMultipleTag1(XPathExpression expr,Document doc) {
try {
NodeList typeResult = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < typeResult.getLength(); i++) {
Node typeResultNode = typeResult.item(i);
System.out.println(typeResultNode.getTextContent());
}
} catch (XPathExpressionException e) {
throw new RuntimeException("Failed parsing expression",e);
}
return null;
}
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
String s="<ex><DtTm><TxDtTm><Cd>ABCD</Cd><dt>1234</dt></TxDtTm><TxDtTm><Cd>XYZ</Cd><dt>891</dt></TxDtTm></DtTm></ex>";
InputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8));
DocumentBuilder db= XpathInstanceUtil.getDocumentBuilderFactory().newDocumentBuilder();
Document doc = db.parse(inputStream);
XPath xpath = XpathInstanceUtil.getXPathFactory().newXPath();
XPathExpression expr = xpath.compile("/ex/DtTm/TxDtTm");
inputStream.close();
long st = System.currentTimeMillis();
getNodeContentForMultipleTag1(expr, doc);
long end = System.currentTimeMillis();
System.out.println(end-st);
long st1 = System.currentTimeMillis();
getNodeContentForMultipleTag1(expr, doc);
long end1 = System.currentTimeMillis();
System.out.println(end1-st1);
}
如果 Cd 值为 ABCD,我应该得到 1234 结果。 我尝试过以下方法
public static String getNodeContentForMultipleTag(String expresssion,String expectedNode,String expectedExpressionTag,Document doc) {
try {
XPath xpath = XpathInstanceUtil.getXPathFactory().newXPath();
NodeList typeResult = (NodeList) evaluateXPath(doc,expresssion,xpath,XPathConstants.NODESET);
NodeList valueResult= (NodeList) evaluateXPath(doc,expectedExpressionTag,xpath,XPathConstants.NODESET);
//NodeList typeResult = (NodeList) xpath.evaluate(expresssion,doc, XPathConstants.NODESET);
//NodeList valueResult = (NodeList) xpath.evaluate(expectedExpressionTag,doc, XPathConstants.NODESET);
for (int i = 0; i < typeResult.getLength(); i++) {
Node typeResultNode = typeResult.item(i);
typeResultNode.getParentNode().removeChild(typeResultNode);
Node valueResultNode = valueResult.item(i);
if(typeResultNode.getTextContent().equals(expectedNode) && valueResultNode!=null){
valueResultNode.getParentNode().removeChild(valueResultNode);
return valueResultNode.getTextContent();
}
}
} catch (XPathExpressionException e) {
throw new RuntimeException("Failed parsing expression"+expresssion,e);
}
return null;
}
这就是表达式的样子
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
String s="<ex><DtTm><TxDtTm><Cd>ABCD</Cd><dt>1234</dt></TxDtTm><TxDtTm><Cd>XYZ</Cd><dt>891</dt></TxDtTm></DtTm></ex>";
InputStream inputStream = new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8));
DocumentBuilder db= XpathInstanceUtil.getDocumentBuilderFactory().newDocumentBuilder();
Document doc = db.parse(inputStream);
String ss = getNodeContentForMultipleTag("/ex/DtTm/TxDtTm/Cd", "XYZ", "/ex/DtTm/TxDtTm/dt", doc);
System.out.println(ss);
}
但是它的性能很低,应该如何修改才能高效解析
最佳答案
这段代码看起来很奇怪。为什么使用 Java 而不是 XPath 来完成所有这些工作?为什么在搜索时要修改 DOM 树?
您只需执行 XPath 表达式 /ex/DtTm/TxDtTm[Cd='ABCD']/dt
即可。
关于java - 使用预编译 xpath 的条件 xpath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43866228/