Извлечение текста из XML-файла

Что касается вопроса как такового, это два последних вопроса из исходного поста:

  • Как я могу надежно использовать nft без вмешательства правил iptables?
  • Или мне просто использовать iptables и удалить nft?

это то, что nftables wiki говорит:

What happens when you mix Iptables and Nftables?
How do they interact?

nft       Empty     Accept  Accept      Block        Blank
iptables  Empty     Empty   Block       Accept       Accept
Results   Pass      Pass    Unreachable Unreachable  Pass 

Так что не стоит беспокоиться о том, что какой-то трафик будет разрешен, потому что он был разрешен в одном инструменте, а запрещен в другом.

Что касается тех правил iptables, как я спросил, «после перезагрузки системы в цепочках iptables есть некоторые правила, которые я не устанавливал (и я понятия не имею, откуда они берутся )» , они пришли из libvirtd.service, которую я отключил, так как она мне не нужна. Но это не повредило бы, даже если бы я этого не сделал.

0
16.05.2021, 22:57
1 ответ

Использованиеxq(части yq,jq-подобной коллекции синтаксических анализаторов для YAML, XML и TOML из https://kislyuk.github.io/yq/), поскольку xmlstarletслишком строго относится к отсутствующему объявлению пространства имен (, см. конец в любом случае вопрос о xmlstarletрешении ).

xq -r --arg title "OYSTER" --arg class "NAME" '
    (.. | select(."@d:title"? == $title)) |
    (.. | select(."@class"?   == $class))."#text"' file.xml

Это рекурсивно выбирает любой узел документа, который имеет d:titleатрибут (, начальный @, используемый в выражении, обозначает атрибут узла, а не имя узла ), которое имеет значение OYSTER.

Учитывая эти узлы (только один в примере ),они рекурсивно ищутся для любого узла, который имеет атрибут classсо значением NAME.

Для каждого такого узла извлекается значение узла.

Две строки OYSTERи NAMEпривязаны к внутренним переменным в командной строке с опцией --arg.

Вывод, учитывая документ в вопросе:

GUYBRUSH THREEPWOOD

Если другие узлы, кроме d:entry, могут иметь атрибут d:titleи/или другие узлы, кроме span, могут иметь атрибут class, и вы хотите избежать сопоставления этих атрибутов в узле неправильного типа, тогда убедитесь, что вы смотрите только в соответствующие узлы:

xq -r --arg title "OYSTER" --arg class "NAME" '
    (.. |."d:entry"? | select(."@d:title"? == $title)) |
    (.. |.span?[]?   | select(."@class"?   == $class))."#text"' file.xml

В качестве справки, поскольку xqфактически вызывает jqс документом JSON за кулисами, ниже приведен документ JSON, в который переведен ваш XML-документ:

{
  "root": {
    "d:entry": {
      "@d:title": "OYSTER",
      "span": [
        {
          "@class": "foot",
          "span": {
            "@role": "text",
            "#text": "foo"
          }
        },
        {
          "@class": "sg",
          "span": {
            "@id": "004",
            "span": [
              {
                "@role": "text",
                "span": {
                  "@class": "pos",
                  "span": {
                    "@class": "baz",
                    "#text": "tart"
                  },
                  "d:pos": null
                }
              },
              {
                "@id": "005",
                "@class": "star",
                "span": [
                  {
                    "@class": "NAME",
                    "d:def": null,
                    "#text": "GUYBRUSH THREEPWOOD"
                  },
                  {
                    "@role": "text",
                    "@class": "bar",
                    "#text": ":"
                  },
                  {
                    "@role": "text",
                    "@class": "grog",
                    "span": [
                      {
                        "@class": "ex",
                        "#text": "pirate"
                      },
                      {
                        "@class": "parrot",
                        "#text": "."
                      }
                    ]
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  }
}

Предполагая, что в документе есть правильное объявление пространства имен d, xmlstarletможно использовать для извлечения нужного текста следующим образом:

xmlstarlet sel -t \
    -m '//d:entry[@d:title = "OYSTER"]' \
    -v '//span[@class = "NAME"]' -nl file.xml

Или, с внутренними переменными, установленными в командной строке с помощью--var(обратите внимание на включение кавычек в значения ),

xmlstarlet sel -t --var title='"OYSTER"' --var class='"NAME"' \
    -m '//d:entry[@d:title = $title]' \
    -v '//span[@class = $class]' -nl file

Оба они начинаются с сопоставления любого узла d:entry, чей атрибут d:titleравен OYSTER. Для каждого такого совпадающего узла он рекурсивно ищет spanузлов с атрибутом classсо значением NAME. Выводится значение каждого такого узла.

1
28.07.2021, 11:31

Теги

Похожие вопросы