在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 node =(Node)xPath.evaluate(expression,masterCbCollDocument,XPathConstants.NODE);
这是为什么?
XPath表达式(//的用法)是否有问题? 是因为推迟了Document的具体实现,所以文件IO太多了吗?
有人可以建议替代方法吗?
答案 0 :(得分:0)
另一种方法是避免使用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);
在这种情况下,masterCbCollDocument.getElementsByTagName
与//signals
XPath表达式具有相同的作用。然后将NodeList中生成的signal
元素映射到它们各自的ID,并返回它们中的最大值。