Adicionando uma linha a um arquivo XML após tags específicas

Adicionando uma linha a um arquivo XML após tags específicas

Como vocês adicionariam uma linha a vários arquivos XML após determinadas tags? A solução pode ser baseada no uso de ferramentas Unix ou nomear um editor de texto ou utilitário que me permita fazer isso de forma rápida e fácil. Tenho mais de 60 arquivos que preciso editar.

Por exemplo, tenho o seguinte XML:

  <Node disablePersistence="true">
     <Name>Mapper</Name>
     <Action>
        <Class-Name>com.test.component.Mapper</Class-Name>
        <Param name="output_url" value="constant:file:///output.xml"/>
        <Param name="xml_url" value="constant:file:///input.xml"/>
        <Param name="xsl_url" value="constant:file:///template.xsl"/>
     </Action>
     <Next-Node>ComposeMessage</Next-Node>
  </Node>

Primeiro eu precisaria procurar pela tag Node. Então eu precisaria procurar pela tag Name=Mapper. Em seguida, procure pela tag Action. Em seguida, procure pela tag Param. Onde estão todas as tags para Param, precisamos inserir a nova linha:

        <Param name="new_parameter" value="constant:true"/>

Isso é possível ou é pedir demais e será mais rápido editar manualmente todos os arquivos?

Responder1

Aqui está, uma solução usando xmlstarletXPath. Estendi o XML para demonstrar que podemos selecionar nós específicos:

Solução

xmlstarlet edit \
    --subnode '//Node[Name/text()="Mapper"]/Action' --type elem --name 'Param' \
    --var nap '$prev' \
    --insert '$nap' --type attr --name 'name' --value 'new_parameter' \
    --insert '$nap' --type attr --name 'constant:true'

Criamos um novo subnó Node/Actiononde também existe um elemento Nameque possui o valor text Mapper. Atribuímos este novo nó à variável XPath nappara que possamos referenciá-lo facilmente. Finalmente, inserimos dois atributos nele.

XML de exemplo

<root>
<Node disablePersistence="true">
    <Name>Mapper</Name>
    <Action>
        <Class-Name>com.test.component.Mapper</Class-Name>
        <Param name="output_url" value="constant:file:///output.xml"/>
        <Param name="xml_url" value="constant:file:///input.xml"/>
        <Param name="xsl_url" value="constant:file:///template.xsl"/>
    </Action>
    <Next-Node>ComposeMessage</Next-Node>
</Node>
<Node disablePersistence="true">
    <Name>DoNotTouchMe</Name>
    <Action>
        <Class-Name>com.test.component.Mapper</Class-Name>
        <Param name="output_url" value="constant:file:///output.xml"/>
        <Param name="xml_url" value="constant:file:///input.xml"/>
        <Param name="xsl_url" value="constant:file:///template.xsl"/>
    </Action>
    <Next-Node>ComposeMessage</Next-Node>
</Node>
</root>

Resultado

<root>
<Node disablePersistence="true">
    <Name>Mapper</Name>
    <Action>
        <Class-Name>com.test.component.Mapper</Class-Name>
        <Param name="output_url" value="constant:file:///output.xml"/>
        <Param name="xml_url" value="constant:file:///input.xml"/>
        <Param name="xsl_url" value="constant:file:///template.xsl"/>
        <Param name="new_parameter" constant:true=""/>
    </Action>
    <Next-Node>ComposeMessage</Next-Node>
</Node>
<Node disablePersistence="true">
    <Name>DoNotTouchMe</Name>
    <Action>
        <Class-Name>com.test.component.Mapper</Class-Name>
        <Param name="output_url" value="constant:file:///output.xml"/>
        <Param name="xml_url" value="constant:file:///input.xml"/>
        <Param name="xsl_url" value="constant:file:///template.xsl"/>
    </Action>
    <Next-Node>ComposeMessage</Next-Node>
</Node>
</root>

informação relacionada