Условное извлечение атрибутов XML с помощью xmlstarlet - PullRequest
0 голосов
/ 01 мая 2018

У меня есть некоторый XML (скажем, файл minimal.xml ), который содержит сообщения об ошибках и предупреждения в следующем формате:

<?xml version="1.0" encoding="UTF-8"?>
  <messages>
     <message subMessage="RSC-004">RSC-004, ERROR, [File 'OEBPS/Text/pdfMigration.html' could not be decrypted.], epub20_encryption_binary_content.epub</message>
     <message subMessage="RSC-012">RSC-012, ERROR, [Fragment identifier is not defined.], OEBPS/toc.ncx (24-67)</message>
     <message subMessage="RSC-012">RSC-012, ERROR, [Fragment identifier is not defined.], OEBPS/toc.ncx (30-82)</message>
     <message subMessage="RSC-012">RSC-012, ERROR, [Fragment identifier is not defined.], OEBPS/toc.ncx (36-81)</message>
     <message subMessage="RSC-012">RSC-012, ERROR, [Fragment identifier is not defined.], OEBPS/toc.ncx (42-75)</message>
     <message subMessage="RSC-012">RSC-012, ERROR, [Fragment identifier is not defined.], OEBPS/toc.ncx (48-61)</message>
     <message subMessage="HTM-023">HTM-023, WARN, [An invalid XHTML Named Entity was found: '&amp;0;'.], OEBPS/Text/pdfMigration.html (18-199)</message>
     <message subMessage="HTM-023">HTM-023, WARN, [An invalid XHTML Named Entity was found: '&amp;l0xb'.], OEBPS/Text/pdfMigration.html (291-6)</message>
  </messages>

Я ищу способ извлечь значение атрибута subMessage для всех сообщений элементов, которые представляют ОШИБКУ (которая может быть определена по наличию ОШИБКИ в message текстовое значение элемента). Я использую xmlstarlet. После некоторых поисков я обнаружил этот несколько похожий случай , поэтому я адаптировал его следующим образом:

xmlstarlet sel -t -v '/messages[contains(message,"ERROR")]/message/@subMessage' minimal.xml

Результат:

RSC-004
RSC-012
RSC-012
RSC-012
RSC-012
RSC-012
HTM-023
HTM-023

Это не то, что я ожидал, так как это subMessage значений всех элементов сообщения! В качестве дальнейшего теста я изменил запрос, чтобы извлечь только предупреждения:

xmlstarlet sel -t -v '/messages[contains(message,"WARN")]/message/@subMessage' minimal.xml

В этом случае результат пуст! Я довольно новичок в xmlstarlet и подозреваю, что упускаю из виду нечто очевидное. Любая помощь с благодарностью!

Кстати, некоторая информация о версии xmlstarlet, которую я использую:

скомпилировано с libxml2 2.9.2, связано с 20903 скомпилировано с libxslt 1.1.28, связано с 10128

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Вам нужно переместить предикат в message, например:

xmlstarlet sel -t -v "/messages/message[contains(.,'WARN')]/@subMessage" minimal.xml
0 голосов
/ 01 мая 2018

Попробуйте это

xmlstarlet sel -t -v '/messages/message[contains(.,"ERROR")]/@subMessage' minimal.xml

С помощью /messages[contains(message,"WARN")] вы ошибочно пытались проверить содержимое элемента messages, а не каждого элемента message.

...