объединить xml атрибут элемента - PullRequest
1 голос
/ 29 января 2020

У меня есть вход xml

<IndexCatalogueRecord SeriesNumber="1" SeriesVolume="3" SeriesPage="594">
<IndexCatalogueID>10305941390</IndexCatalogueID>
<GeneralNote>[Shelved in: B.58]</GeneralNote>
<GeneralNote>[Shelved in: B.458]</GeneralNote>
<GeneralNote>[Shelved in: B.20]</GeneralNote>
<Language>fr</Language>
</IndexCatalogueRecord>

, и мне нужно решение для объединения атрибутов элемента GeneralNote, разделенных запятыми, чтобы он стал

<IndexCatalogueRecord SeriesNumber="1" SeriesVolume="3" SeriesPage="594">
<IndexCatalogueID>10305941390</IndexCatalogueID>
<GeneralNote>[Shelved in: B.58, B.458, B.20]</GeneralNote>
<Language>fr</Language>
</IndexCatalogueRecord>

Мой подход было иметь xmlstarlet запросить элемент для значения атрибута, а затем передать это для обработки с помощью grep или awk. Я могу легко получить значение атрибута из GeneralNote, используя xmlstarlet

 xmlstarlet sel -t -m "//GeneralNote" -v . -n test.xml

, но когда я попытался передать консольный вывод в grep, чтобы он обрезал совпадающую строку "[Shelved in:" and "]" У меня возникли проблемы, пожалуйста, дайте мне знать, если есть более элегантное решение. заранее спасибо

1 Ответ

2 голосов
/ 29 января 2020

Один из возможных подходов - использование двух вложенных xmlstarlet команд
(обратите внимание на два вхождения имени файла в выражении):

xmlstarlet ed -u "/IndexCatalogueRecord/GeneralNote[1]" \
  -v "$(xmlstarlet sel -t -o "[Shelved in: " -m "/IndexCatalogueRecord/GeneralNote" \
  -v "substring-after(substring-before(.,']'),'[Shelved in: ')" \
  --if 'position() != last()' -o ', ' -b -b -o "]" input.xml)" \
  -d "/IndexCatalogueRecord/GeneralNote[position() > 1]" input.xml

Внутренняя команда xmlstarlet создает окончательный вариант значение из всех GeneralNote элементов, а внешняя команда обновляет первый элемент GeneralNote и удаляет другой. В xmlstarlet ed - режим редактирования значения, а sel - режим выбора значения.

  • -u - означает обновление значения
  • -v - извлекает значение с помощью XPath
  • -m - выполняет итерацию по всем узлам, соответствующим выражению XPath
  • -o - выводит строку c
  • -b - завершает итерацию или предложение if
  • -d - удаляет все узлы, соответствующие XPath

. Если вы хотите изменить XML на месте , добавьте Опция -L сразу после xmlstarlet ed.

...