Localizar-substituir dentro da hierarquia de arquivos XML

0

Tenho cerca de 350 arquivos XML espalhados pelo diretório /abc . Eu gostaria de encontrar todas as instâncias onde o valor do atributo alt é exatamente ' blá blá ':

<image alt="blah blah" src="../webcontent/filename.png">
    <caption>
        Figure 1.1: Typical Components of Blah Blah
    </caption>
</image>

e substitua o valor do atributo alt pelo conteúdo entre caption (remoção de novas linhas)

<image alt="Figure 1.1: Typical Components of Blah Blah" src="../webcontent/filename.png">
    <caption>
        Figure 1.1: Typical Components of Blah Blah
    </caption>
</image>

Estou aberto para executar um script no Ubuntu ou no Windows ou usando qualquer ferramenta de edição de texto.

Não é seguro assumir que as linhas novas e o recuo são consistentes. Além disso, nem todas as imagens têm uma legenda. Todos os documentos XML no caminho são bem formados.

Existe uma maneira simples de fazer o script dessa substituição no local? Eu estaria aberto para algo que funciona para um único arquivo; Eu posso estendê-lo para executar recursivamente.

    
por Jedi 17.06.2016 / 15:37

2 respostas

1

Para um único arquivo, a seguinte folha de estilo XSLT fará o trabalho:

<t:transform version="1.0" xmlns:t="http://www.w3.org/1999/XSL/Transform">
  <t:template match="node()|@*">
    <t:copy>
      <t:apply-templates select="node()|@*"/>
    </t:copy>
  </t:template>
  <t:template match="image/@alt[. = 'blah blah']">
    <t:attribute name="alt" select="normalize-space(../caption)"/>
  </t:template>
</t:transform>

Para processar vários arquivos, você pode invocar a folha de estilos várias vezes a partir de algum script de shell, script Ant ou similar (ou consultar xmlsh) ou, se estiver usando um processador XSLT 2.0 como Saxon, pode criar scripts dentro do próprio XSLT usando a função collection ()

    
por 17.06.2016 / 16:59
0

Você também pode usar xmlstarlet :

xmlstarlet ed -u '//image/@alt[.= "blah blah"]' -x "normalize-space(../caption/text())"
    
por 21.06.2016 / 10:54