【问题标题】:Fast processing of large XML file快速处理大型 XML 文件
【发布时间】:2013-08-15 21:18:09
【问题描述】:

我在 VB.NET 中有一个很大的 XMLNode(我们说的是 10s/100s 的数千个节点和数百万个属性)。

XML 的一般结构是:

<other xml nodes></other xml nodes>
<list>
    <item attr1="" attr2="" attr3="" attr4="" ... />
    <item attr1="" attr2="" attr3="" attr4="" ... />
    <item attr1="" attr2="" attr3="" attr4="" ... />
    <item attr1="" attr2="" attr3="" attr4="" ... />
    <item attr1="" attr2="" attr3="" attr4="" ... />
    <item attr1="" attr2="" attr3="" attr4="" ... />
    .
    .
    .
</list>

我想要做的是根据某些属性删除项目节点(例如,如果我有 50,000 个节点,我的标准可能会删除其中的 49500 个)。

我的问题是,我的代码需要几秒钟才能删除这么多的节点,我需要它更快。

我尝试了几种不同的方法,我迄今为止最快的是:

dim xnlList = xnBigXMLNode.selectNodes("//list/item[@attr1=sample]")
for each xnNode in xnlList
    xnNode.ParentNode.RemoveChild(xnNode)
next

*请原谅以上代码中的任何错误,我现在不在我的开发机器上

作为一个附加的约束,我需要在 xmlNode 中保留“其他 xml 节点”。

我考虑过删除整个列表,然后重新添加我需要的节点,但这需要更长的时间才能执行。

有人能想出一种方法来更快地删除数千个节点吗?

提前致谢

【问题讨论】:

  • 听起来像一个非常大的文件。考虑 NTFS 分配不是连续的,并且 HDD 的平均随机读取速度小于 5MB/s。硬盘可能是你的瓶颈,而不是你的代码。
  • @GiulioFranco 我实际上是从 web 服务获取 XML,但是单步执行代码,很明显有一些瓶颈 - 一个是从 web 服务获取 xml,另一个是删除如此大量的节点。感谢您的建议。
  • 看看你是怎么写示例结构的,xml的结构似乎很简单。即使这很难维护,您是否考虑过在明文上使用明文/正则表达式匹配?

标签: xml vb.net xmlnode


【解决方案1】:

看起来像是编写 SAX 过滤器的经典案例。解析器生成 SAX 事件并将它们传递给您的应用程序,您的应用程序将事件的子集传递给序列化程序,序列化程序会生成新的 XML 文件。无需在内存中构建树。

作为一名 Java 人,我不知道如何在 VB 中执行此操作的详细信息,但该技术确实存在。

【讨论】:

  • 我的 C# 有 XMLReader 这是一个 STaX 解析器。类似,但它是拉式解析器,而不是推式解析器(区别在于驱动解析的是用户,而不是解析器调用接口上的方法)
  • 是的,您也可以使用拉式解析器。就个人而言,我发现对于像这样的简单过滤器,推送方法更简单,但许多程序员更愿意编写拥有主控制循环的程序部分。
  • @MichaelKay 感谢您的回答,我曾考虑编写自己的解析器,但我会查找 .net 的 SAX 样式解析器
  • 如果可以的话,我认为在获取的同时执行 xml 解析会很好。由于 I/O 比 CPU 慢,因此您的 CPU 解析 XML 所花费的时间将完全被网络延迟所掩盖。
【解决方案2】:

我已经找到了一个需要几毫秒才能运行的解决方案(而不是之前需要几秒钟)。

事实证明:

dim xnlList = xnBigXMLNode.selectNodes("//list/item[@attr1=sample]")
for each xnNode in xnlList
    xnNode.ParentNode.RemoveChild(xnNode)
next

需要几秒钟才能运行,而:

dim xnlList = xnBigXMLNode.selectNodes("//list/item")
for each xnNode in xnlList
    xnNode.ParentNode.RemoveChild(xnNode)
next

需要几毫秒。

所以在我的循环中,我编写了代码来测试每个节点的所需属性,并适当地删除了。

感谢其他答案中的所有有用建议。

【讨论】:

    猜你喜欢
    • 2021-04-17
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 2018-03-06
    • 1970-01-01
    • 2014-05-23
    • 2020-11-06
    相关资源
    最近更新 更多