
У меня около 350 XML-файлов, разбросанных по всему /abc
каталогу. Я хотел бы найти все случаи, где значение атрибута alt точно равно 'бла-бла':
<image alt="blah blah" src="../webcontent/filename.png">
<caption>
Figure 1.1: Typical Components of Blah Blah
</caption>
</image>
и замените значение атрибута alt
содержимым, заключенным в скобки caption
(удалив символы новой строки)
<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>
Я открыт для запуска скрипта в Ubuntu или Windows, или с использованием любого текстового редактора.
Небезопасно предполагать, что новые строки и отступы согласованы. Кроме того, не все изображения имеют подпись. Все XML-документы в пути имеют правильный формат.
Есть ли простой способ написать скрипт этой замены на месте? Я бы с радостью взял что-то, что работает для одного файла; я могу расширить его для рекурсивного запуска.
решение1
Для одного файла подойдет следующая таблица стилей XSLT:
<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>
Для обработки нескольких файлов вы можете вызвать таблицу стилей несколько раз из какого-нибудь скрипта оболочки, скрипта Ant или подобного (или посмотрите на xmlsh), или, если вы используете процессор XSLT 2.0, такой как Saxon, вы можете написать скрипт внутри самого XSLT, используя функцию collection()
решение2
Вы также можете использовать xmlstarlet
:
xmlstarlet ed -u '//image/@alt[.= "blah blah"]' -x "normalize-space(../caption/text())"