Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java XOM规范化耗时太长_Java_Xml_Performance_Canonicalization_Xom - Fatal编程技术网

Java XOM规范化耗时太长

Java XOM规范化耗时太长,java,xml,performance,canonicalization,xom,Java,Xml,Performance,Canonicalization,Xom,我有一个高达1GB的XML文件。我使用XOM来避免OutOfMemory异常 我需要规范化整个文档,但规范化需要很长时间,即使是1.5MB的文件 以下是我所做的: 我有这个示例XML文件,我通过复制Item节点来增加文档的大小 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <Packet id="some" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&

我有一个高达1GB的XML文件。我使用XOM来避免OutOfMemory异常

我需要规范化整个文档,但规范化需要很长时间,即使是1.5MB的文件

以下是我所做的:

我有这个示例XML文件,我通过复制Item节点来增加文档的大小

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Packet id="some" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Head>
<PacketId>a34567890</PacketId>
<PacketHeadItem1>12345</PacketHeadItem1>
<PacketHeadItem2>1</PacketHeadItem2>
<PacketHeadItem3>18</PacketHeadItem3>
<PacketHeadItem4/>
<PacketHeadItem5>12082011111408</PacketHeadItem5>
<PacketHeadItem6>1</PacketHeadItem6>
</Head>
<List id="list">
    <Item>
        <Item1>item1</Item1>
        <Item2>item2</Item2>
        <Item3>item3</Item3>
        <Item4>item4</Item4>
        <Item5>item5</Item5>
        <Item6>item6</Item6>
        <Item7>item7</Item7>
    </Item>
</List>
</Packet>
尽管这段代码适用于小文件,但在我的开发环境(4gb ram、64位、eclipse、windows)上,1.5mb文件的规范化部分大约需要7分钟

我们非常感谢任何指向此延迟原因的指针

另外,我需要规范化整个XML文档中的片段,以及整个文档本身。因此,使用文档本身作为参数对我不起作用

最佳

内部节点在列表中管理,并进行线性比较。 列表中的项目越多,“包含”将变慢

private final List nodes;
public boolean contains(Node node) {
    return nodes.contains(node);
}
所以

  • 尝试修改lib的代码,以使用HashMap保存节点
  • 或者使用多线程来利用更多的CPU,如果您的XML可以拆分成小的XML

工具:JVisualVM

既然您希望整个文档序列化,您能替换

Nodes nodes = doc.getRootElement().query("./descendant-or-self::node()|./@*");
outputter.write(nodes);

?

当给定要规范化的节点列表而不是根节点时,
Canonicalizer
似乎会执行额外的工作(例如whunmr提到的
nodes.contains()
调用)


如果这不起作用或者还不够,我会使用
规范化工具
,并按照评测建议在那里进行优化。

如果您愿意放弃XOM,我可能会找到解决您问题的方法。我的解决方案包括使用and

性能上的差异令人印象深刻,但我认为最好提供一个比较

在测试中,我使用了您在问题中提供的1.5MB的XML文件

XOM测试 XPath/Santuario测试 结果

下表以秒为单位列出了结果。试验进行了16次

╔═════════════════╦═════════╦═══════════╗
║      Test       ║ Average ║ Std. Dev. ║
╠═════════════════╬═════════╬═══════════╣
║ XOM             ║ 140.433 ║   4.851   ║
╠═════════════════╬═════════╬═══════════╣
║ XPath/Santuario ║ 2.4585  ║  0.11187  ║
╚═════════════════╩═════════╩═══════════╝
性能上的差异是巨大的,它与。使用XPath/Santuario的缺点是它们不像XOM那么简单

测试细节 机器:英特尔Core i5 4GB内存
SO:Debian 6.0 64位
Java:OpenJDK 1.6.01864位
XOM:1.2.8

ApacheSantuario:1.5.3

我觉得您的原始XML文件非常规范。什么是不规范的?谢谢你的回答。很有见地。你认为有更有效的方法规范化节点吗?不确定。如果您仍然想使用这个库,也许可以尝试使用HashMap来保存节点,从而修改库的代码。或者尝试其他LIB或方法。:)如果您的XML可以拆分成小的XML,那么您可以使用多线程来利用更多的CPU。因为目前你的应用程序在一个CPU中已经接近100%。使用更多的CPU显然可以减少应用程序的运行时间。实际上,我需要规范化XML文档中的片段。我意识到这个例子有点误导;我必须规范化列表节点。因此,我不一定希望规范化整个文档。
Nodes.contains is the most busy one
private final List nodes;
public boolean contains(Node node) {
    return nodes.contains(node);
}
Nodes nodes = doc.getRootElement().query("./descendant-or-self::node()|./@*");
outputter.write(nodes);
outputter.write(doc);
FileInputStream xmlFile = new FileInputStream("input.xml");

Builder builder = new Builder(false);
Document doc = builder.build(xmlFile);

FileOutputStream fos = new FileOutputStream("output.xml");
nu.xom.canonical.Canonicalizer outputter = new nu.xom.canonical.Canonicalizer(fos);

Nodes nodes = doc.getRootElement().query("./descendant-or-self::node()|./@*");
outputter.write(nodes);

fos.close();
org.apache.xml.security.Init.init();

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.parse("input.xml");

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

org.w3c.dom.NodeList result = (org.w3c.dom.NodeList) xpath.evaluate("./descendant-or-self::node()|./@*", doc, XPathConstants.NODESET);

Canonicalizer canon = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
byte canonXmlBytes[] = canon.canonicalizeXPathNodeSet(result);

IOUtils.write(canonXmlBytes, new FileOutputStream(new File("output.xml")));
╔═════════════════╦═════════╦═══════════╗
║      Test       ║ Average ║ Std. Dev. ║
╠═════════════════╬═════════╬═══════════╣
║ XOM             ║ 140.433 ║   4.851   ║
╠═════════════════╬═════════╬═══════════╣
║ XPath/Santuario ║ 2.4585  ║  0.11187  ║
╚═════════════════╩═════════╩═══════════╝