【问题标题】:What is the fastest way to remove nodes from a large XML file using .net使用 .net 从大型 XML 文件中删除节点的最快方法是什么
【发布时间】:2010-01-12 03:45:15
【问题描述】:

我正在处理非常大的 XML 文件(数百 MB)。这棵树相当简单

<items>
  <item>
    <column1>ABC</column1>
    <column2>DEF</column2>
  </item>
  <item>
    <column1>GHI</column1>
    <column2>KLM</column2>
  </item>
</items>

我需要解析这个文档,并删除一些&lt;item&gt; 元素。到目前为止,我实现的最佳性能是使用 XmlReader,将每个 &lt;item&gt; 缓存在内存中,如果符合标准,则使用 XmlWriter 将其写回,如果不符合标准,则简单地忽略它。我能做些什么来让它更快吗?

【问题讨论】:

  • 您在寻找 .Net 解决方案吗?
  • 是的,我正在寻找 .net,很抱歉没有澄清这一点
  • 你现在看到什么样的性能,你需要多快?这是一次性迁移(即遍历所有现有文档并删除“坏”数据)还是正在进行的操作(即我们每 N 分钟收到这些 100MB 文档,并且需要在使用它们之前清理它们)?
  • 该文件将每天进入一次,但由用户指定节点删除条件。一个 250MB 的文档需要 30 秒才能运行,我希望它快 10 倍。将其转换为不同的格式(如 JSON)是一种替代方法,假设它会给我们带来更好的性能。
  • 30 秒,每天一次似乎不是优化的高价值候选...除非用户指定他们的节点删除标准然后抱怨 30 秒太长而无法等待“净化”的 XML 文档。

标签: xml performance parsing


【解决方案1】:

您可以通过实现 XmlReader 的子类来节省一步,该子类的 Read 方法跳过您不感兴趣的 item 元素。现在,您似乎有两个步骤:读取和过滤带有XmlReader 的文档,然后使用XmlWriter 将其写入您可能会从中读取的内容。子类化XmlReader 消除了第二步;您使用子类 XmlReader 作为 XSLT 转换或 XmlDocument 或其他任何东西的输入,它永远不会构建过滤后的 XML 文档的中间表示。

【讨论】:

  • 这可能有效,但是一旦我向前阅读,如果我的项目是好的,我需要将我的“光标”移回项目的开头。我该怎么做?
  • 嗯,有(至少)两种方法。您可以让您的 XmlReader 在创建时检查其 Stream 的 CanSeek 属性,如果无法查找则抛出异常;那么你知道你可以在开始解析元素时将位置保存在 Stream 中,如果元素很好,你可以再次解析它。更好的方法是为每个节点构建某种中间表示 - XmlNodeType、Name、Value 等 - 并将其保存在列表中。然后要么抛出列表,要么在调用 Read 时从列表中的下一项更新 XmlReader 的属性。
【解决方案2】:

如果您可以编写一个快速的正则表达式来摆脱它,您可以使用 perl 或 shell 脚本来替换所需的项目。这样可以避免将整个内容加载到内存中并将其写回。

【讨论】:

  • 一般来说,正则表达式不能用于匹配XML(或HTML),因为它们不是正则语言。
【解决方案3】:

看看你是否可以使用 xpath 查询来确定你想要和不想用那个 xmldocument 对象读取什么......查看该类的以下方法 SelectSingleNode() 返回一个 XmlNode 对象... SelectNodes() 返回一个 XmlNodeList 对象.... 看看有没有帮助....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 2020-03-16
    • 1970-01-01
    相关资源
    最近更新 更多