如何使用 setAttribute() 插入文字“&”
How to insert a literal '&' using setAttribute()
我正在使用 XML::LibXML (2.0018; perl 5.16.3) 我有一个散列,其中包含一系列属性,然后使用 setAttribute()
将这些属性应用于 XML 文档。这个东西是为了更新一个 tomcat server.xml 需要修改的文件以与 apache httpd 前端一起工作,并由持续部署脚本执行。
添加基本属性效果很好:
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="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
我试过转义(和双重转义)哈希中的条目,例如:
relaxedQueryChars => "[]|{}^\\\`\"\<\>"
不幸的是,在前一种情况下,它只是简单地输入了&#x5c;&#x60
,而在后一种情况下,它在&
之前添加了一个\
。
我如何定义散列中的字符串,以便它通过 setAttribute
进行处理并正确发出 \
?
根据请求,这里有一个完整的例子:
/tmp/min.xml(基本上从 tomcat conf/server.xml 剥离的所有内容):
<?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 => "[]|{}^\\\`\"\<\>"
);
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);
不正确的结果行:
<Connector address="127.0.0.1" relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;" port="8381"/>
我认为基本上你唯一需要的改变是 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="[]|{}<>\&#"/>
您担心 XML 中的反斜杠 "escapes the next character" 不受 Wikipedia 支持 - 符号字符 &
是用于对所有内容进行实体编码的字符有问题的字符。
我正在使用 XML::LibXML (2.0018; perl 5.16.3) 我有一个散列,其中包含一系列属性,然后使用 setAttribute()
将这些属性应用于 XML 文档。这个东西是为了更新一个 tomcat server.xml 需要修改的文件以与 apache httpd 前端一起工作,并由持续部署脚本执行。
添加基本属性效果很好:
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="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
我试过转义(和双重转义)哈希中的条目,例如:
relaxedQueryChars => "[]|{}^\\\`\"\<\>"
不幸的是,在前一种情况下,它只是简单地输入了&#x5c;&#x60
,而在后一种情况下,它在&
之前添加了一个\
。
我如何定义散列中的字符串,以便它通过 setAttribute
进行处理并正确发出 \
?
根据请求,这里有一个完整的例子:
/tmp/min.xml(基本上从 tomcat conf/server.xml 剥离的所有内容):
<?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 => "[]|{}^\\\`\"\<\>"
);
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);
不正确的结果行:
<Connector address="127.0.0.1" relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;" port="8381"/>
我认为基本上你唯一需要的改变是 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="[]|{}<>\&#"/>
您担心 XML 中的反斜杠 "escapes the next character" 不受 Wikipedia 支持 - 符号字符 &
是用于对所有内容进行实体编码的字符有问题的字符。