java - DeferredDocumentImpl 上的 XPath 需要很长时间来评估
问题描述
在 Java 中,我从这样的文件加载一个 XML 文件,它返回一个 DeferredDocumentImpl
private Document loadMasterFileXml(String path)
{
File masterFilePath = new File(path);
DocumentBuilderFactory masterDocBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder masterDocBuilder = masterCbcCollBuilderFactory.newDocumentBuilder();
masterDocument = masterDocBuilder.parse(masterFilePath);
return masterDocument;
}
XML 文件包含大约 1000 个元素,如下所示:
<com.something.something.Collection xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:com.something.something.model="http://www.something.com/something.1.0.0" xmi:id="_HklwsJnWEeeaddrVFPWCMg" name="SOME_THING">
<signals xmi:id="_N0ir0ZnWEeeaddrVFPWCMg" id="10000">
<signal href="#_6M0edJhNEeeNvfntr9AQ8g"/>
</signals>
<signals xmi:id="_N0jS4JnWEeeaddrVFPWCMg" id="10001">
<signal href="#_6M1FgJhNEeeNvfntr9AQ8g"/>
</signals>
...
对该文档执行的第一个 XPath 操作如下:
public long getMaximumSignalIdFromMasterDocument()
{
Integer errorCode=-1;
try
{
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xPath = xPathfactory.newXPath();
String expression = "//signals[not(@id < //signals/@id)]";
Node node = (Node) xPath.evaluate(expression, masterCbCollDocument, XPathConstants.NODE);
return Long.parseLong(node.getAttributes().getNamedItem("id").getNodeValue());
}
catch(Exception e)
{
return errorCode;
}
}
在调试模式下,以下行需要超过 1 小时才能执行。
节点节点 = (Node) xPath.evaluate(表达式, masterCbCollDocument, XPathConstants.NODE);
为什么是这样?
XPath 表达式是否有问题(使用 //)?是因为文档的具体实现被推迟了,所以文件 IO 太多了吗?
任何人都可以提出另一种方法吗?
解决方案
另一种方法是避免使用 XPath。尽管长达一小时的计算似乎更可能成为您使用的调试器/IDE 的问题,但 XPath 表达式的效率也不是很高 (O(n^2)),并且无法在 XPath 1.0 中得到显着优化。在这种情况下直接使用 Java 似乎更合适。一种方法可以是:
NodeList signals = masterCbCollDocument.getElementsByTagName("signals");
long result = IntStream.range(0, signals.getLength()).mapToLong(i -> Long.parseLong(((Element)signals.item(i)).getAttribute("id"))).max().orElse(-1);
在这种情况下,它的作用与 XPath 表达式masterCbCollDocument.getElementsByTagName
相同。//signals
然后将 NodeList 中的结果signal
元素映射到它们各自的 ID,并返回其中的最大值。
推荐阅读
- php - opencart 2.1.0.2-save percent in category.php & 分页/过滤器问题
- python - 从 iPython / Jupyter 嵌入式 Qt 控制台获取结果对象
- c# - 如何处理模拟对象?
- ios - 'BMPhotosViewController' 没有可见的@interface 声明选择器'initWithPhoto:'
- javascript - 当 onOpen 存在时测试作为附加组件会导致错误
- exception-handling - 在 Spring 5 Reactive kotlin 中处理异常
- javascript - 奇怪的 html textarea 错误
- netlogo - 我自己的话在 Netlogo 中给出了一个错误
- c# - 如何使用 ssml 韵律元素产生情感演讲?
- javascript - 初学者查询:使用带有for循环的函数参数,由于某种原因跳过循环