Как вы используете опцию --pattern для xmllint?

Я пытаюсь понять, как libxml реализует поддержку XPath, поэтому мне было полезно проверить с помощью xmllint. Однако очевидный вариант, --pattern, несколько неясен, и я в итоге использовал что-то вроде следующего:

test.xml: <foo><bar/><bar/></foo>

> xmllint --shell test.xml
/  > dir /foo
ELEMENT foo
/  > dir /foo/*
ELEMENT bar
ELEMENT bar

Кажется, это работает, и это здорово, но мне все еще интересно. Что такое параметр xmllint --pattern и как он работает?

Укажите пример полного кредита. =)

Ответы

Ответ 1

Подсказка заключается в словах "которые могут использоваться с интерфейсом считывателя для анализатора": xmllint использует интерфейс считывателя при передаче опции -stream:

$ xmllint --stream --pattern /foo/bar test.xml
Node /foo/bar[1] matches pattern /foo/bar
Node /foo/bar matches pattern /foo/bar

Ответ 2

Похоже, что недокументированная опция --xpath представляется более полезной.

% cat data.xml
<project>
  <name>
    bob
  </name>
  <version>
    1.1.1
  </version>
</project>
% xmllint --xpath '/project/version/text()' data.xml | xargs -i echo -n "{}"
1.1.1
% xmllint --xpath '/project/name/text()' data.xml | xargs -i echo -n "{}"
bob

Ответ 3

На странице руководства xmllint (1):

   --pattern PATTERNVALUE
          Used to exercise the pattern recognition engine, which can be
          used with the reader interface to the parser. It allows to
          select some nodes in the document based on an XPath (subset)
          expression. Used for debugging.

Он понимает только подмножество XPath, и его намерение заключается в помощи в отладке. Библиотека, которая полностью понимает XPath, - это libxslt (3) и инструмент командной строки xsltproc (1).

Модуль `` pattern '' в libxml позволяет компилировать и тестировать выражения шаблонов для узлов либо в дереве, либо на основе состояния парсера ", и его документация живет здесь: http://xmlsoft.org/html/libxml-pattern.html

Ари.

Ответ 4

Если вам просто нужно текстовое значение для нескольких узлов xml, вы можете использовать что-то вроде этого (если -xpath недоступен в вашей версии xmllint):

./foo.xml:

<hello>
   <world>its alive!!</world>
   <world>and works!!</world>
</hello>

$ xmllint --stream --pattern /hello/world --debug ./foo.xml | grep -A 1 "matches pattern" | grep "#text" | sed 's/.* [0-9] //'
its alive!!
and works!!