3

我的问题如下:

我必须阅读一个大的 XML 文件,50 MB;并匿名一些与私人问题相关的标签/字段,如姓名、姓氏地址、电子邮件、电话号码等......

我确切地知道 XML 中的哪些标签要匿名。

 s|<a>alpha</a>|MD5ed(alpha)|e;
 s|<h>beta</h>|MD5ed(beta)|e;

wherealphabeta引用其中的任何字符,这些字符也将被散列,可能使用像MD5这样的算法。

我只会转换标签值,而不是标签本身。

我希望,我对我的问题足够清楚。我如何实现这一目标?

4

4 回答 4

6

您必须在 Python 中执行以下操作。

import xml.etree.ElementTree as xml # or lxml or whatever
import hashlib
theDoc= xml.parse( "sample.xml" )
for alphaTag in theDoc.findall( "xpath/to/tag" ):
    print alphaTag, alphaTag.text
    alphaTag.text = hashlib.md5(alphaTag.text).hexdigest()
xml.dump(theDoc)
于 2009-02-19T15:47:59.983 回答
4

底线:不要使用正则表达式解析 XML。

请改用您的语言的 DOM 解析库,如果您知道需要匿名化的元素,请使用 XPath 获取它们并通过设置它们的 innerText/innerHTML 属性(或您的语言所称的任何内容)来散列它们的内容。

于 2009-02-19T15:35:02.633 回答
4

使用正则表达式确实很危险,除非您确切知道文件的格式,否则使用正则表达式很容易解析,并且您确定它将来不会改变。

否则,您确实可以使用 XML::Twig,如下所示。另一种方法是使用 XML::LibXML,尽管文件可能有点大,无法完全加载到内存中(同样,也许不是,现在内存很便宜)所以你可能不得不使用拉模式,我不太了解。

紧凑的 XML::Twig 代码:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;
use Digest::MD5 'md5_base64';

my @tags_to_anonymize= qw( name surname address email phone);

# the handler for each element ($_) sets its content with the md5 and then flushes
my %handlers= map { $_ => sub { $_->set_text( md5_base64( $_->text))->flush } } @tags_to_anonymize;

XML::Twig->new( twig_roots => \%handlers, twig_print_outside_roots => 1)
         ->parsefile( "my_big_file.xml")
         ->flush;
于 2009-02-19T19:32:37.423 回答
3

正如 Welbog 所说,不要尝试使用正则表达式解析 XML。你最终会后悔的。

可能最简单的方法是使用XML::Twig。它可以分块处理 XML,这使您可以处理非常大的文件。

另一种可能性是使用SAX,尤其是XML::SAX::Machines。我自己从来没有真正使用过它,但它是一个面向流的系统,所以它应该能够处理大文件。缺点是您可能必须编写更多代码来收集您关心的每个标签内的文本(XML::Twig 将为您收集该文本)。

于 2009-02-19T16:27:18.623 回答