【问题标题】:How to in-place parse and edit huge xml file [duplicate]如何就地解析和编辑巨大的xml文件[重复]
【发布时间】:2019-07-26 17:45:02
【问题描述】:

我有大量的 XML 数据集 (2-40GB)。一些数据是机密的,所以我正在尝试编辑数据集以屏蔽所有机密信息。我有一长串需要屏蔽的每个值,例如,如果我有 ID 'GYT-1064',我需要查找并替换它的每个实例。这些值可以位于不同的字段/级别/子类中,因此在一个对象中它可能具有“Order-ID = GYT-1064”,而另一个可能会显示“PO-Name = GYT-1064”。我已经研究了 iterparse,但无法弄清楚如何就地编辑 xml 文件而不是在内存中构建整个新树,因为我必须多次遍历它才能找到每个 ID 的每个实例。

理想的功能:

对于每个元素,如果给定的字符串在元素中,则替换文本并更改 XML 文件中的行。

如果数据集足够小以加载到内存中,我有一个可行的解决方案,但我不知道如何正确利用 iterparse。我还研究了所有关于 lxml iterparse 的答案,但是由于我需要多次遍历整个文件,所以我需要能够就地编辑它

有效的简单版本,但必须将整个 xml 加载到内存中(并且不是就地)

values_to_mask = ['val1', 'GMX-103', 'etc-555'] #imported list of vals to mask

with open(dataset_name, encoding='utf8') as f:

    tree = ET.parse(f)
    root = tree.getroot()

    for old in values_to_mask:
            new = mu.generateNew(old, randomnumber) #utility to generate new amt
            for elem in root.iter():
                try:
                    elem.text = elem.text.replace(old, new)
                except AttributeError:
                    pass

tree.write(output_name, encoding='utf8')

我对 iterparse 的尝试:

with open(output_name, mode='rb+') as f:
    context = etree.iterparse( f )
    for old in values_to_mask:
        new = mu.generateNew(old, randomnumber)
        mu.fast_iter(context, mu.replace_if_exists, old, new, f)

def replace_if_exists(elem, old, new, xf):
try:
    if(old in elem.text):
        elem.text = elem.text.replace(old, new)
        xf.write(elem)
except AttributeError:
    pass

它运行但不替换任何文本,我得到 print(context.root) = 'Null'。此外,它似乎不会正确地写回原位文件。

XML 数据的基本外观(带有子类的分层对象)

一般是这样的:

<Master_Data_Object>
 <Package>
      <PackageNr>1000</PackageNr>
      <Quantity>900</Quantity>
      <ID>FAKE_CONFIDENTIALGYO421</ID>
      <Item_subclass>
        <ItemType>C</ItemType>
        <MasterPackageID>FAKE_CONFIDENTIALGYO421</MasterPackageID>
 <Package>
 <Other_Types>

【问题讨论】:

  • 更新了帖子以显示一些 XML 数据
  • 这是将 XML 转换为 pandas 数据框的可靠演练,此时过滤数据集和应用掩码非常有效:medium.com/@robertopreste/…

标签: python xml parsing


【解决方案1】:

由于缺乏数据集,我想建议你

1) 在循环中使用readlines() 一次读取大量数据

2) 使用正则表达式来识别机密信息(如果可能)然后替换它。

让我知道它是否有效

【讨论】:

    【解决方案2】:

    您几乎可以将 SAX 解析器用于大型 xml 文件。 这是你的答案- Editing big xml files using sax parser

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-22
      • 2013-02-06
      • 1970-01-01
      • 2010-10-29
      • 2012-07-09
      • 1970-01-01
      相关资源
      最近更新 更多