Подтвердить что ты не робот

Как разбирать XML с помощью shellscript?

Я хотел бы знать, что было бы лучшим способом анализа XML файла с помощью shellscript?

  • Если это сделать вручную?
  • Существует ли библиотека третьего уровня?

Если вы уже сделали это, если бы могли сообщить мне, как вам удалось это сделать

4b9b3361

Ответ 1

Вы можете попробовать xmllint

Программа xmllint анализирует один или несколько XML файлы, указанные в команде строка как xmlfile. Он печатает различные типы продукции, в зависимости от выбранные опции. Это полезно для обнаружение ошибок как в XML-коде, так и в в парсере XML itse

Он позволяет вам выбирать элементы в XML-документе по xpath, используя опцию -pattern.

В Mac OS X (Yosemite) он устанавливается по умолчанию.
На Ubuntu, если он еще не установлен, вы можете запустить apt-get install libxml2-utils

Ответ 2

Вот полный рабочий пример.
Если он только извлекает адреса электронной почты, вы можете просто сделать что-то вроде:
1) Предположим, что файл XML spam.xml похож на

<spam>
<victims>
  <victim>
    <name>The Pope</name>
    <email>[email protected]</email>
    <is_satan>0</is_satan>
  </victim>
  <victim>
    <name>George Bush</name>
    <email>[email protected]</email>
    <is_satan>1</is_satan>
  </victim>
  <victim>
    <name>George Bush Jr</name>
    <email>[email protected]</email>
    <is_satan>0</is_satan>
  </victim>
</victims>
</spam>

2) Вы можете получить электронные письма и обработать их с помощью этого короткого кода bash:

#!/bin/bash
emails=($(grep -oP '(?<=email>)[^<]+' "/my_path/spam.xml"))

for i in ${!emails[*]}
do
  echo "$i" "${emails[$i]}"
  # instead of echo use the values to send emails, etc
done

Результат этого примера:

0 [email protected]
1 [email protected]
2 [email protected]

Важное примечание:
Не используйте это для серьезных вопросов. Это нормально для игры, получения быстрых результатов, обучения grep и т.д., Но вам обязательно нужно искать, изучать и использовать парсер XML для производства (см. Комментарий Micha ниже).

Ответ 4

Я удивлен, что никто не упомянул xmlsh. Заявление миссии:

Командная строка для XML. Основываясь на философии и дизайне Unix Shells

xmlsh предоставляет знакомую среду сценариев, но конкретно разработанный для сценариев xml-процессов.

Список команд, подобных оболочке, предоставляется здесь.

Я использую команду xed много, что эквивалентно sed для XML и позволяет XPath искать и заменять.

Ответ 5

Попробуйте sgrep. Не ясно, что именно вы пытаетесь сделать, но я, конечно же, не стал бы писать парсер XML в bash.

Ответ 6

У вас установлен xml_grep? Это стандартная утилита на основе perl для некоторых дистрибутивов (она была предварительно установлена ​​на моей системе CentOS). Вместо того, чтобы давать ему регулярное выражение, вы даете ему выражение xpath.

Ответ 9

Это действительно выходит за рамки возможностей оболочки script. Shell script и стандартные инструменты Unix подходят для парсинга строк, ориентированных на файлы, но все меняется, когда вы говорите об XML. Даже простые теги могут представлять проблему:

<MYTAG>Data</MYTAG>

<MYTAG>
     Data
</MYTAG>

<MYTAG param="value">Data</MYTAG>

<MYTAG><ANOTHER_TAG>Data
</ANOTHER_TAG><MYTAG>

Представьте, что вы пытаетесь написать оболочку script, которая может читать вложенные данные. Три очень, очень простых XML-примера показывают разные способы, которыми это может быть проблемой. Первые два примера - это тот же самый синтаксис в XML. Третий просто имеет атрибут, прикрепленный к нему. Четвертый содержит данные в другом теге. Простые команды sed, awk и grep не могут уловить все возможности.

Вам нужно использовать полномасштабный язык сценариев, такой как Perl, Python или Ruby. Каждый из них имеет модули, которые могут анализировать XML-данные и облегчать доступ к базовой структуре. Я использую XML:: Simple в Perl. Мне потребовалось несколько попыток понять это, но он сделал то, что мне было нужно, и облегчил мне программирование.

Ответ 11

Здесь решение с использованием xml_grep (потому что xpath не был частью нашего дистрибутива, и я не хотел его добавлять на все производственные машины)...

Если вы ищете определенный параметр в файле XML, и если все элементы на заданном уровне дерева уникальны и нет атрибутов, вы можете использовать эту удобную функцию:

# File to be parsed
xmlFile="xxxxxxx"

# use xml_grep to find settings in an XML file
# Input ($1): path to setting
function getXmlSetting() {

    # Filter out the element name for parsing
    local element=`echo $1 | sed 's/^.*\///'`

    # Verify the element is not empty
    local check=${element:?getXmlSetting invalid input: $1}

    # Parse out the CDATA from the XML element
    # 1) Find the element (xml_grep)
    # 2) Remove newlines (tr -d \n)
    # 3) Extract CDATA by looking for *element> CDATA <element*
    # 4) Remove leading and trailing spaces
    local getXmlSettingResult=`xml_grep --cond $1 $xmlFile 2>/dev/null | tr -d '\n' | sed -n -e "s/.*$element>[[:space:]]*\([^[:space:]].*[^[:space:]]\)[[:space:]]*<\/$element.*/\1/p"`

    # Return the result
    echo $getXmlSettingResult
}

#EXAMPLE
logPath=`getXmlSetting //config/logs/path`
check=${logPath:?"XML file missing //config/logs/path"}

Это будет работать с этой структурой:

<config>
  <logs>
     <path>/path/to/logs</path>
  <logs>
</config>

Он также будет работать с этим (но он не будет содержать символы новой строки):

<config>
  <logs>
     <path>
          /path/to/logs
     </path>
  <logs>
</config>

Если у вас есть duplicate <config> или <logs> или < путь > , тогда он будет возвращать только последний. Вероятно, вы можете изменить функцию, чтобы возвращать массив, если он находит несколько совпадений.

FYI: Этот код работает на RedHat 6.3 с GNU BASH 4.1.2, но я не думаю, что я делаю что-то особенное, поэтому должен работать везде.

ПРИМЕЧАНИЕ. Для кого-то нового для сценариев, убедитесь, что вы используете правильные типы кавычек, все три используются в этом коде (обычная одиночная кавычка = буквенная, обратная одиночная кавычка = выполнение и двойная кавычка = группа).