如何用另一个通用文本的内容替换XML元素的文本内容?

时间:2013-09-25 13:21:09

标签: xml perl

我处理来自飞机制造商B的数据。我需要将这些数据提供给第三方,以便他们开发可以操纵它的工具。
问题是数据需要匿名化,因为我们与B签订了保密协议。所以每当我们有像

这样的元素时
<element>Some really sensitive information</element>  

我们需要用非敏感内容替换文本内容。 我可以使用perl one-liner,用*替换所有字母数字字符。

perl -ne 'if(/<(PARA)>([^<]*)<\/PARA>(.*)/){$tag = $1;$content = $2; $content =~ s/\S/*/g;print "<".$tag.">".$content."</".$tag.">".$3."\n"}else{print $_;}' infile > outfile

然而,因为我想让匿名数据更具可读性,而相关工具更易于解决问题,我想插入“真实”文本而不是*,但需要注意的是entrie文本内容需要长度相同。单个单词更改长度没有问题,但整个文本内容必须具有相同的长度。

所以结果将是“lorem ipsum”类型的东西。

这样做的一个缺点是,我最终得到了所有<title>元素,例如,具有相同的开头,例如<title>Lorem Ipsum</title> & <title>Lorem Ips</title>对于一个人类读者而言,不那么容易分辨 因此,最终的解决方案是我有一个文本文件可供使用,我将从该文本块中的随机起点选择正确长度的文本块。 (我想到马塞尔普鲁斯特的一个地方只是为了自命不凡)

如果有人能像perl单行一样做,我会永远敬畏 认为目标元素总是在一条线上,元素只包含文本,没有子元素或属性。

1 个答案:

答案 0 :(得分:4)

好的,这是一个正确的方法,使用XML解析器和所有,在(非常!)长行:

perl -MText::Lorem -MXML::Twig -E'$t= Text::Lorem->new; XML::Twig->parse( twig_roots => { PARA => sub { $l= length $_->text; $_->set_text( substr( $t->words( $l), 0, $l)); $_->flush} }, twig_print_outside_roots => 1, keep_spaces => 1, $ARGV[0])' myfile.xml

走正则路线:

perl -MText::Lorem -p -E'BEGIN { $t= Text::Lorem->new; } s{<PARA>(.*)</PARA>}{$l=length $1; "<PARA>" . substr( $t->words( $l), 0, $l) . "</PARA>"}eg' myfile.xml

如果要更改文件inplace

,请使用-i

在这两种情况下,由于Text :: Lorem不允许指定生成的字符串的字符数,因此我生成一个(更长的)字符串,然后获取适当长度的子字符串。我怀疑你可以使用$l/2生成的单词数量,它仍然可以正常工作。