我有一个 xml 文件,其中包含以下详细信息:
<server>
<mbean code="WSMQConnectionFactory" name="service=MQQueueConnectionFactory">
<attribute name="JndiName">WSMQQueueConnectionFactory</attribute>
<attribute name="QueueManagerName">QMPMP</attribute>
<attribute name="HostName">10.10.20.21</attribute>
<attribute name="Channel">CHANNEL01</attribute>
<attribute name="TransportType">MQJMS_TP_CLIENT_MQ_TCPIP</attribute>
<depends>jboss:service=Naming</depends>
</mbean>
</server>
我想搜索“HostName”属性并在其后添加新属性(端口)。它应该看起来像这样:
<server>
<mbean code="WSMQConnectionFactory" name="service=MQQueueConnectionFactory">
<attribute name="JndiName">WSMQQueueConnectionFactory</attribute>
<attribute name="QueueManagerName">QMPMP</attribute>
<attribute name="HostName">10.10.20.21</attribute>
<attribute name="Port">1414</attribute>
<attribute name="Channel">CHANNEL01</attribute>
<attribute name="TransportType">MQJMS_TP_CLIENT_MQ_TCPIP</attribute>
<depends>jboss:service=Naming</depends>
</mbean>
</server>
请建议
答案1
请不要这样做。 XML 是一种结构化数据类型,它不“适合”正则表达式。虽然您可以假装您的 XML 是纯文本,并使用例如“sed”来调整它,但这是创建脆弱代码的一种非常好的方法 - 因为不同的 XML 结构在语义上是相同的行不通以同样的方式。
为此,您确实需要一个解析器。我建议使用 Perl(它无处不在),而且XML::Twig
它非常常见且易于安装。
这段代码可以做到这一点(它比实际的长一点)需要是,但这是为了清楚起见)。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
sub paste_port {
my ( $twig, $attribute ) = @_;
my $port_attr =
XML::Twig::Elt->new( 'attribute', { 'name' => 'Port' }, 1414 );
print "Inserting:\n", $port_attr->sprint, "\n";
$port_attr->paste_after($attribute);
}
my $twig = XML::Twig->new(
'pretty_print' => 'indented',
'twig_handlers' => { 'attribute[@name="HostName"]', \&paste_port }
);
$twig->parsefile('your_xml.xml');
$twig->print;
#save to file 'new_xml.xml'
open( my $output_file, ">", "new_xml.xml" ) or warn $!;
print {$output_file} $twig->sprint;
close($output_file);
这将产生输出:
<server>
<mbean code="WSMQConnectionFactory" name="service=MQQueueConnectionFactory">
<attribute name="JndiName">WSMQQueueConnectionFactory</attribute>
<attribute name="QueueManagerName">QMPMP</attribute>
<attribute name="HostName">10.10.20.21</attribute>
<attribute name="Port">1414</attribute>
<attribute name="Channel">CHANNEL01</attribute>
<attribute name="TransportType">MQJMS_TP_CLIENT_MQ_TCPIP</attribute>
<depends>jboss:service=Naming</depends>
</mbean>
</server>
答案2
试试这个方法:
sed -i -r 's/(.*HostName.*)/\1\n<attribute name="Port">1414<\/attribute>/g' filename
导致:
$ cat filename
<server>
<mbean code="WSMQConnectionFactory" name="service=MQQueueConnectionFactory">
<attribute name="JndiName">WSMQQueueConnectionFactory</attribute>
<attribute name="QueueManagerName">QMPMP</attribute>
<attribute name="HostName">10.10.20.21</attribute>
<attribute name="Port">1414</attribute>
<attribute name="Channel">CHANNEL01</attribute>
<attribute name="TransportType">MQJMS_TP_CLIENT_MQ_TCPIP</attribute>
<depends>jboss:service=Naming</depends>
</mbean>
</server>