请考虑以下代码段:
my $PRSR = XML::LibXML->new();
my $PP = XML::LibXML::PrettyPrint->new(indent_string => " ");
my $tmRawData = <DATA>;
my $tmDOM = $PRSR->load_xml(string => $tmRawData);
my $hm="SHA-1";
say $tmDOM->findvalue('//checksum[checksumMethod="' . $hm .'"]/checksumValue');
my $prettyxml = $PP->pretty_print($tmDOM->documentElement())->toString();
say $tmDOM->findvalue('//checksum[checksumMethod="' . $hm .'"]/checksumValue');
say $prettyxml;
__DATA__
<checksum> <checksumMethod>SHA-1</checksumMethod> <checksumValue>56db195fc75e93509133193bfe5608eaeef2c471</checksumValue> </checksum>
第一个说将正确打印出哈希值。第二个说将打印一个空字符串。显然,pretty_print通过用空格填充它们来更改所有元素值,以便在打印时看起来很漂亮。我可以在xpath中使用“contains”来解决这个肮脏的方式,但那会很脏。
现在我的第一个(也是迄今为止唯一的)想法就是简单地复制DOM对象,以便pretty_print可以搞砸一个而不用另外一个,就像这样:
my $PRSR = XML::LibXML->new();
my $PP = XML::LibXML::PrettyPrint->new(indent_string => " ");
my $tmRawData = <DATA>;
my $tmDOM = $PRSR->load_xml(string => $tmRawData);
my $hm="SHA-1";
say $tmDOM->findvalue('//checksum[checksumMethod="' . $hm .'"]/checksumValue');
my $tmDOM2 = $tmDOM;
my $prettyxml = $PP->pretty_print($tmDOM2->documentElement())->toString();
say $tmDOM->findvalue('//checksum[checksumMethod="' . $hm .'"]/checksumValue');
__DATA__
<checksum> <checksumMethod>SHA-1</checksumMethod> <checksumValue>56db195fc75e93509133193bfe5608eaeef2c471</checksumValue> </checksum>
但这会产生完全相同的结果。
答案 0 :(得分:1)
问题:为什么不将tmDOM复制到另一个变量tmDOM2来解决这个问题?
因为您正在复制参考。就像这样:
my $x = [ 1 .. 9 ];
my $y = $x; # copy $x to $y to protect it from changes to $x
push @$x, 10; # change $x
print "$_\n" for @$y; # d'oh! we changed $y too
问题:有没有办法阻止pretty_print搞乱元素值?
阅读文档。特别是,搜索preserves_whitespace
选项,它允许您告诉XML :: LibXML :: PrettyPrint保留特定元素中的空格。
答案 1 :(得分:1)
使用cloneNode
方法获取同一DOM节点的新副本。
my $PP = 'XML::LibXML::PrettyPrint'->new( indent_string => ' ' );
my $tmRawData = <DATA>;
my $tmDOM = 'XML::LibXML'->load_xml( string => $tmRawData );
my $tmDOM2 = $tmDOM->cloneNode(1); # <--- HERE
my $hm = 'SHA-1';
say '1: ', $tmDOM->findvalue("//checksum[checksumMethod='$hm']/checksumValue");
my $prettyxml = $PP->pretty_print($tmDOM->documentElement)->toString;
say '2: ', $tmDOM2->findvalue("//checksum[checksumMethod='$hm']/checksumValue");
say '3: ', $prettyxml;