![Buscar y reemplazar dentro de la jerarquía de archivos XML](https://rvso.com/image/1497070/Buscar%20y%20reemplazar%20dentro%20de%20la%20jerarqu%C3%ADa%20de%20archivos%20XML.png)
Tengo alrededor de 350 archivos XML repartidos por todo el /abc
directorio. Me gustaría encontrar todos los casos en los que el valor del atributo alt es exactamente 'bla, bla':
<image alt="blah blah" src="../webcontent/filename.png">
<caption>
Figure 1.1: Typical Components of Blah Blah
</caption>
</image>
y reemplace el valor del alt
atributo con el contenido encerrado por caption
(eliminando nuevas líneas)
<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>
Estoy abierto a ejecutar un script en Ubuntu o Windows, o utilizar cualquier herramienta de edición de texto.
No es seguro asumir que las nuevas líneas y la sangría sean consistentes. Además, no todas las imágenes tienen un título. Todos los documentos XML de la ruta están bien formados.
¿Existe una forma sencilla de programar este reemplazo in situ? Estaría abierto a algo que funcione para un solo archivo; Puedo extenderlo para que se ejecute de forma recursiva.
Respuesta1
Para un solo archivo, la siguiente hoja de estilo XSLT hará el trabajo:
<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 procesar múltiples archivos, puede invocar la hoja de estilo varias veces desde algún script de shell, script Ant o similar (o mire xmlsh), o si está usando un procesador XSLT 2.0 como Saxon, puede escribirlo dentro del propio XSLT. usando la función colección()
Respuesta2
También podrías usar xmlstarlet
:
xmlstarlet ed -u '//image/@alt[.= "blah blah"]' -x "normalize-space(../caption/text())"