Как разбирать XML с помощью shellscript?
Я хотел бы знать, что было бы лучшим способом анализа XML файла с помощью shellscript?
- Если это сделать вручную?
- Существует ли библиотека третьего уровня?
Если вы уже сделали это, если бы могли сообщить мне, как вам удалось это сделать
Ответы
Ответ 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 ниже).
Ответ 3
Также есть xmlstarlet (который также доступен для Windows).
http://xmlstar.sourceforge.net/doc/xmlstarlet.txt
Ответ 4
Я удивлен, что никто не упомянул xmlsh. Заявление миссии:
Командная строка для XML. Основываясь на философии и дизайне Unix Shells
xmlsh предоставляет знакомую среду сценариев, но конкретно разработанный для сценариев xml-процессов.
Список команд, подобных оболочке, предоставляется здесь.
Я использую команду xed
много, что эквивалентно sed
для XML и позволяет XPath
искать и заменять.
Ответ 5
Попробуйте sgrep. Не ясно, что именно вы пытаетесь сделать, но я, конечно же, не стал бы писать парсер XML в bash.
Ответ 6
У вас установлен xml_grep? Это стандартная утилита на основе perl для некоторых дистрибутивов (она была предварительно установлена на моей системе CentOS). Вместо того, чтобы давать ему регулярное выражение, вы даете ему выражение xpath.
Ответ 7
Довольно новый проект - это пакет xml-coreutils, содержащий xml-cat, xml-cp, xml-cut, xml-grep,...
http://xml-coreutils.sourceforge.net/contents.html
Ответ 8
Попробуйте использовать xpath. Вы можете использовать его для анализа элементов из дерева xml.
http://www.ibm.com/developerworks/xml/library/x-tipclp/index.html
Ответ 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. Мне потребовалось несколько попыток понять это, но он сделал то, что мне было нужно, и облегчил мне программирование.
Ответ 10
Здесь функция, которая преобразует пары и атрибуты имени и имени XML в переменные bash.
http://www.humbug.in/2010/parse-simple-xml-files-using-bash-extract-name-value-pairs-and-attributes/
Ответ 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, но я не думаю, что я делаю что-то особенное, поэтому должен работать везде.
ПРИМЕЧАНИЕ. Для кого-то нового для сценариев, убедитесь, что вы используете правильные типы кавычек, все три используются в этом коде (обычная одиночная кавычка = буквенная, обратная одиночная кавычка = выполнение и двойная кавычка = группа).