Adicionando novo atributo ao arquivo xml existente usando sed ou awk

1

Eu tenho um arquivo xml que contém os detalhes abaixo:

<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>

Eu quero procurar um atributo "HostName" e adicionar novo atributo (porta) após ele. Deve ficar assim:

<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>

Por favor, sugira

    
por pandeg 04.03.2015 / 21:50

2 respostas

1

Por favor, não faça isso. XML é um tipo de dados estruturado e é aquele que não se encaixa em uma expressão regular. Enquanto você pode fingir que seu XML é texto simples, e use, por exemplo, 'sed' para ajustá-lo, esta é uma maneira muito boa de criar códigos frágeis - porque diferentes estruturas XML que são semanticamente idênticas não funcionarão da mesma maneira.

Para fazer isso, você realmente precisa de um analisador. Gostaria de sugerir Perl (que é onipresente) e XML::Twig , que é bastante comum e facilmente instalado.

Este código irá fazê-lo (é um pouco mais do que realmente precisa para ser, mas isso é no interesse da clareza).

#!/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);

Isso produzirá a saída:

<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>
    
por 28.04.2015 / 14:16
0

Tente desta maneira:

sed -i -r 's/(.*HostName.*)/\n<attribute name="Port">1414<\/attribute>/g' filename

Resultado em:

$ 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>
    
por 04.03.2015 / 22:00

Tags