Para remover uma tag de um arquivo xml

0

Meu arquivo contém dados que não são bem identificados. Diga como:

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namspace/Service/1.0"><Record>
.
.</Record></ns0:collection>

Eu tenho que marcar o número N desses arquivos e criar um arquivo. Então eu preciso que o seguinte seja feito:

  1. Preciso remover apenas a tag de fechamento </ns0:collection> do primeiro arquivo
  2. remova os arquivos <?xml version="1.0" encoding="UTF-8" ?><ns0:collection xmlns:ns0="http://namspace/Service/1.0"> e </ns0:collection> nos próximos (n-1) arquivos
  3. É preciso remover somente <?xml version="1.0" encoding="UTF-8" ?><ns0:collection xmlns:ns0="http://namspace/Service/1.0"> no último arquivo e mesclar todos juntos

Eu tentei usar o comando sed para processar o primeiro arquivo que não está resultando em nada, "merged.xml" está vazio.

sed '/<\/ns0:collection>/d' $file1 > merged.xml

Alguma sugestão?

    
por Varsha Gowda 10.01.2018 / 09:41

3 respostas

3

Você não especificou que só pode usar sed , portanto, se tiver acesso a xml_grep (consulte Mesclar vários arquivos XML da linha commend , segunda resposta), eu recomendaria isso porque ele faz muito do trabalho pesado para você e para um trabalho simples de mesclagem como este pode ser feito em um comando:

xml_grep --cond Record --wrap "ns0:collection" --descr 'xmlns:ns0="http://namespace/Service/1.0"' --encoding "UTF-8" *.xml

Arquivos de teste:

test.xml

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namespace/Service/1.0""><Record>
Test
</Record></ns0:collection>

test1.xml

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namespace/Service/1.0"><Record>
Test 1<a>a</a><b c="c">d</b>
</Record></ns0:collection>

Resultado

<?xml version="1.0" encoding="UTF-8" ?>
<ns0:collection xmlns:ns0="http://namespace/Service/1.0">
<Record>
Test 1<a>a</a><b c="c">d</b></Record><Record>
Test
</Record>
</ns0:collection>

Eu prefiro usar ferramentas com reconhecimento de XML ao lidar com arquivos XML, porque a chance de atrapalhar a estrutura com sed e amigos é bastante alta e você pode facilmente acabar com um documento XML malformado!

    
por 10.01.2018 / 16:13
0

Sugiro que usar sed não é bom para processar XML e, em vez disso, usar um analisador.

Também sugiro que você tenha um problema XY aqui - não se trata de excluir tags, mas sim de mesclar arquivos XML.

Pessoalmente, gosto de perl e XML::Twig :

#!/usr/bin/env perl
use strict;
use warnings;

#load the parser
use XML::Twig; 

#get our file list - we use the "first" file as the basis.
#can use sort on this list if desired. 
my ( $first_file, @other_files ) = glob ( 'C://tmp//xmltest/*.xml' ); 

#Our 'parent' document. 
my $doc = XML::Twig -> new -> parsefile ( $first_file ); 


foreach my $file ( @other_files ) { 
   my $mergedoc = XML::Twig -> new -> parsefile ( $file ); 

   #//Record means any <Record> node anywhere in the tree. 
   foreach my $record ( $mergedoc -> get_xpath ( '//Record' ) ) {
      $record -> cut;
      #paste it into our parent doc, as the last node. 
      $record -> paste ( after => $doc -> root -> last_child );
   }
}

#set output formatting (optional)
$doc -> set_pretty_print ('indented_a'); 

#print to STDOUT.
$doc -> print;

#write to output file too
open ( my $output, '>', 'combined.xml' ) or die $!;
print {$output} $doc -> sprint;
close ( $output );

Isso extrai deliberadamente os elementos Record do XML de destino e apenas os mescla entre os documentos. No entanto, é uma abordagem flexível - xpath é bastante poderoso e é o equivalente XML de regex - mas funciona melhor porque é sensível ao contexto, onde regex não é.

    
por 12.01.2018 / 11:47
0

Soluções:

  1. Eu preciso remover apenas a tag de fechamento do primeiro arquivo, solution:

    sed -i.bak -e 's/<\/ns0:collection>/ /' -e 's/<\/Record>/ /' n0
    
  2. remova os arquivos <?xml version="1.0" encoding="UTF-8" ?><ns0:collection xmlns:ns0="http://namspace/Service/1.0"> e </ns0:collection> nos próximos (n-1) arquivos:

    sed -i.bak -e 's/<?xml version=1.0 encoding=UTF-8 ?>.*<ns0:collection/ /' -e 's/xmlns.*/ /' -e 's/<\/R.*>.*>/ /' n1
    
    • Fazendo isso para o intervalo do nome do arquivo:

      find . -type f -name "n[1-3]" -exec sed i.bak -e 's/<?xml version=1.0 encoding=UTF-8 ?>.*<ns0:collection/ /' -e 's/xmlns.*/ /' -e 's/<\/R.*>.*>/ /' {} \;
      
  3. Tem que remover apenas no último arquivo e mesclar todos juntos:

    sed i.bak -e 's/<?xml version=1.0 encoding=UTF-8 ?>.*<ns0:collection/ /' -e 's/xmlns.*/ /' ne
    

Então, finalmente, junte-se a eles:

cat n0 n[1-3] ne > joined

Eu usei os seguintes arquivos: n0 , n1 , n2 , n3 e ne . Eu adicionei o seguinte texto em cada:

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namspace/Service/1.0"><Record>
hello from nigeria
</Record></ns0:collection>

O arquivo resultante joined foi como visto abaixo:

<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namspace/Service/1.0"><Record>
hello from nigeria



hello from nigeria



hello from nigeria



hello from nigeria



hello from nigeria
</Record></ns0:collection>

Nota:

  1. Eu vejo no primeiro problema que você precisa remover os dois </Record></ns0:collection> não apenas </ns0:collection> . Então, tomei a liberdade de fazer, senão teríamos uma entrada </Record> duplicada quando os arquivos fossem mesclados.

  2. Os nomes dos arquivos aqui teriam que ser modificados por você para que você possa executar um comando sobre todos eles, aqui eu usei n[1-3] . Escolha o que funciona melhor para você.

  3. EXECUTE UM TESTE PRIMEIRO E VER OS RESULTADOS , usei i.bak , então sed cria um backup automaticamente.

por 10.01.2018 / 12:13