Добавление строки в файл XML после определенных тегов
Как бы вы, ребята, пошли добавить строку к группе файлов XML после определенных тегов? Решение может быть основано на использовании инструментов Unix или названии текстового редактора или утилиты, которые могут позволить мне сделать это быстро и легко. У меня есть более 60 файлов, которые мне нужно отредактировать.
Например, у меня есть следующий 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>
Сначала мне нужно будет найти тег Node. Тогда мне нужно будет искать тег Name = Mapper. Затем найдите тег Action. Затем найдите тег Param. Там, где находятся все теги для Param, нам нужно вставить новую строку:
<Param name="new_parameter" value="constant:true"/>
Это возможно, или это требует слишком много, и будет быстрее редактировать все файлы вручную?
1 ответ
Итак, решение с использованиемxmlstarlet
и XPath. Я расширил XML, чтобы продемонстрировать, что мы можем выбирать определенные узлы:
Решение
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'
Создаем новый поднодNode/Action
где также есть элементName
который имеет текстовое значениеMapper
. Мы присваиваем этот новый узел переменной XPath.nap
чтобы мы могли легко ссылаться на него. Наконец, мы вставляем в него два атрибута.
Пример XML
<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>
Результат
<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>