如何使用setAttribute()插入文字'&'

时间:2018-11-04 16:29:12

标签: xml perl xml-libxml

我正在使用XML :: LibXML(2.0018; perl 5.16.3),我有一个包含一系列属性的哈希,然后使用$ python t.py ['powerlog', 't', 'com.apple.launchd.pFf62wnsYV', 'com.apple.launchd.bAXuv2WS1L'] /tmp/powerlog 将这些属性应用于XML文档。这些东西是用于更新tomcat server.xml文件,该文件需要进行修改才能与apache httpd前端一起使用,并由连续部署脚本执行。

添加基本属性可以正常工作:

setAttribute()

然后采用某种采用哈希引用的方法:

use XML::LibXML qw ();

...

my %tmphash = ( port => "8581", address => "127.0.0.1", ... );

...

一切顺利,直到现在,我需要在输出中添加需要文字foreach my $key (keys %$hashConnRef) { $connector->setAttribute("$key" => $hasConnRef->{$key}); } 的属性,以便tomcat能够正确拾取它。

要放入server.xml文件中的属性应类似于(所需结果):

&

但是,relaxedQueryChars="[]|{}^\`"<>" 调用方便地将“&”转换为“&”,从而产生(当前输出):

setAttribute()

我尝试对哈希中的条目进行转义(和两次转义),例如:

relaxedQueryChars="[]|{}^\`"<>"

不幸的是,在前一种情况下,它只是放置了relaxedQueryChars => "[]|{}^\\\`\"\<\>" ,而在后一种情况下,它在\&#x60之前添加了\。 如何在哈希中定义字符串,以便它可以处理&并正确发出setAttribute

每个请求,下面是一个完整的示例:

/tmp/min.xml(基本上是从tomcat conf / server.xml中删除的所有内容):

&#x5c

还有一个最小的示例程序:

<?xml version="1.0" encoding="utf-8"?>
<Server port="8385" shutdown="SHUTDOWN">
  <Service name="Catalina">
  </Service>
</Server>

结果行不正确:

#!/usr/bin/perl -w

use strict;
use warnings;

use XML::LibXML qw ( );

my %tmphash = (
  port => "8381",
  address => "127.0.0.1",
  relaxedQueryChars => "[]|{}^\&#x5c;\&#x60;\&quot;\&lt;\&gt;"
  );

sub edit_server_xml {
  my ($serverFile, $hashConnRef) = @_;

  my $parser = XML::LibXML->new();

  my $doc = $parser->parse_file($serverFile);

  for my $server ($doc->findnodes("/Server")) {
    # delete all of the defined connectors
      for my $service ($server->findnodes("Service")) {
        for my $connector ($service->findnodes("Connector")) {
          $service->removeChild($connector);
        }
      }

      my $connector = $doc->createElement("Connector");
      for my $service ($server->findnodes("Service")) {
        foreach my $key (keys %$hashConnRef) {
          $connector->setAttribute("$key" => $hashConnRef->{$key});
        }

        $service->appendChild($connector);
        $service->appendTextNode("\n");
      }

    $doc->toFile($serverFile);
  }
}

edit_server_xml("/tmp/min.xml", \%tmphash);

1 个答案:

答案 0 :(得分:3)

我认为基本上您需要的唯一更改是relaxedQueryChars => "[]|{}^\\\"<>"-不要预先编码内容,libxml将处理所有必要的实体编码:

#!perl
use strict;
use warnings;
use XML::LibXML;

my $doc = XML::LibXML->load_xml(string=>'<f/>');
$doc->documentElement->setAttribute('foo' => '[]|{}<>\\&#');
print $doc->toString

__END__

<?xml version="1.0"?> <f foo="[]|{}&lt;&gt;\&amp;#"/>

Wikipedia不支持XML中的反斜杠“转义下一个字符”,因为&字符&是用于对所有有问题的字符进行实体编码的字符。