我的问题如下:
我必须读取一个大的XML文件,50 MB;并匿名一些与私人问题相关的标签/字段,如姓氏地址,电子邮件,电话号码等......
我确切地知道XML中的哪些标签是匿名的。
s|<a>alpha</a>|MD5ed(alpha)|e;
s|<h>beta</h>|MD5ed(beta)|e;
其中alpha
和beta
引用其中的任何字符,也可以使用像MD5这样的算法进行哈希处理。
我只会转换标记值,而不是标记本身。
我希望,我对我的问题很清楚。我如何实现这一目标?
答案 0 :(得分: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)
答案 1 :(得分:4)
底线:不要使用正则表达式解析XML。
使用您的语言的DOM解析库,如果您知道匿名化所需的元素,请使用XPath获取它们并通过设置innerText / innerHTML属性(或您的语言称之为)来散列其内容。
答案 2 :(得分:4)
使用regexp确实很危险,除非你确切知道文件的格式,使用正则表达式很容易解析,并且你确信它将来不会改变。
否则你确实可以使用XML :: Twig,如下所示。另一种方法是使用XML :: LibXML,虽然文件可能有点大,可以将它完全加载到内存中(然而,也许不是,内存现在很便宜)所以你可能不得不使用拉模式,我不太了解。
Compact 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;
答案 3 :(得分:3)
正如Welbog所说,不要试图用正则表达式解析XML。你最终会后悔的。
可能最简单的方法是使用XML::Twig。它可以以块的形式处理XML,从而可以处理非常大的文件。
另一种可能性是使用SAX,尤其是使用XML::SAX::Machines。我自己从来没有真正使用它,但它是一个面向流的系统,所以它应该能够处理大文件。缺点是您可能需要编写更多代码来收集您关心的每个标记内的文本(XML :: Twig将为您收集该文本)。
答案 4 :(得分:0)
我们开放了我们的工具Paranoid,该工具可让您屏蔽单个XML元素或单个XML文件或XML文件文件夹中的所有元素。
它也可以通过缓冲处理大型XML文件。它还适用于JSON
Paranoid是用Python编写的