【问题标题】:Remove approx 60,000 XML nodes from a huge 3GB XML file - Powershell从一个巨大的 3GB XML 文件中删除大约 60,000 个 XML 节点 - Powershell
【发布时间】:2020-08-05 09:21:54
【问题描述】:

我目前正在尝试从一个巨大的 XML 文件中删除大量数据。我目前正在使用 Powershell 来尝试这样做,我想知道它是否可以在可接受的时间内完成。此文件包含 2.5m 条记录,我想删除属性 = 'COMPANY' 的所有记录。这是我当前的代码:

$xml = [xml]'' 
$xml.Load("C:\New folder\untrimmed.xml")


$node = $xml.SelectSingleNode("//record[@category='COMPANY']")
while ($node -ne $null) {
    $node.ParentNode.RemoveChild($node)
    $node = $xml.SelectSingleNode("//record[@category='COMPANY']")

$xml.save("C:\New folder\trimmed.xml")

在一个半小时后完成此操作后,修剪后的文件比原始文件大。我怎样才能以更好的方式做到这一点? powershell 不适合这里的工作吗?

【问题讨论】:

  • 剪裁后的文件是否使用 UTF-16 编码?
  • While 循环未关闭。您能否提供minimal reproducible exampleXML 示例?
  • 我建议使用 System.Xml.XmlReader 和 XmlWriter 以及读取的元素并将它们流出来,除了您要过滤的元素。如果我没记错的话 [xml] 会读取内存中的整个文件。请参阅此 SO 以了解如何操作:stackoverflow.com/questions/48102318/…
  • @vonPryz 它的 UTF-8

标签: .net xml windows powershell


【解决方案1】:

试用 Saxon 10.0 中的新 Gizmo 工具。

java net.sf.saxon.Gizmo -s:"C:\New folder\untrimmed.xml"
/>delete //record[@category='COMPANY']
/>save C:\New folder\untrimmed.xml
/>quit

警告:我没有尝试使用包含空格的文件名。

不幸的是,Gizmo 目前不使用流式传输(我们有一个可以使用的原型,但尚未发布),因此您需要相当多的内存才能运行它。

如果流式传输是必不可少的,您可以使用流式 XSLT 3.0 样式表来做到这一点:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
               version="3.0">
  <xsl:mode streamable="yes" on-no-match="shallow-copy"/>
  <xsl:template match="record[@category='COMPANY']"/>
</xsl:transform>

【讨论】:

    猜你喜欢
    • 2020-11-05
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 2012-04-19
    • 2012-08-08
    • 1970-01-01
    相关资源
    最近更新 更多