#xml #macos #shell #sed
#xml #macos #оболочка #sed
Вопрос:
Ну, я уже написал скрипт, который в основном принимает XML-файл в качестве входных данных и извлекает текст для определенных XML-тегов, и он работает. Но это недостаточно умно, чтобы получать многострочный текст, а также разрешать специальные символы. Очень важно, чтобы текстовый формат оставался неизменным, поскольку он определен в тегах.
Ниже приведен ввод XML:
<nick>Deminem</nick>
<company>XYZ Solutions</company>
<description>
/**
*
* «Lorem» ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
* tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
* At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
* no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit
* consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore
* magna aliquyam erat, sed diam voluptua.
*
**/
</description>
Приведенный выше скрипт извлекает текст каждого конкретного тега и присваивает ему новое значениеarray. Моя команда над sed является базовой, но всегда готова пройти лишнюю милю.
tagsArray=( nick company description )
noOfElements=${#tagsArray[@]}
for (( i=0;i<$noOfElements;i )); do
OUT=`grep ${tagsArray[${i}]} filename.xml | tr -d 't' | sed -e 's/^<.*>([^<].*)<.*>$/1/' `
valueArray[${i}]=${OUT}
done
Ответ №1:
Разбор XML с помощью regexp в конечном итоге приводит к проблемам, с которыми вы столкнулись. Найдите время, чтобы изучить достаточно XSL (есть много руководств), чтобы правильно преобразовать XML, используя, например, xsltproc.
Редактировать:
Опробовав несколько утилит командной строки xml, я думаю, что xmlstarlet мог бы стать для вас подходящим инструментом. Следующее не проверено и предполагает, что filename.xml
это правильный XML-файл (т. Е. имеет один корневой элемент).
tagsArray=( nick company description )
noOfElements=${#tagsArray[@]}
for (( i=0;i<$noOfElements;i )); do
valueArray[${i}] = `xmlstarlet sel -t -v "/root/$tagsArray[i]" filename.xml`
done
Комментарии:
1. @AnderLindahi — Да, это правда, синтаксический анализ XML через sed / awk — непростая работа, потому что эти инструменты не предназначены для интеллектуальной обработки XML. Но, к сожалению, я должен придерживаться schell script с использованием sed.
2. @AnserLindahi — Поставляется ли xsltproc с предустановленным пакетом в Mac OSX и Unix?
3. @Deminem: Требование использовать shell script похоже на требование, чтобы кто-то срубил дерево отверткой. Это можно сделать, но это некрасиво.
4. @Jim: Требование использовать shell script важно в моем сценарии, потому что я не хочу зависимости от установки какого-либо стороннего инструмента для установки некоторых пользовательских шаблонов , которые можно легко выполнить с помощью shell script. Единственное, что заканчивается чтением настроек конфигурации, которые находятся в формате XML. ЕСЛИ у вас есть какие-либо предложения получше по замене формата данных моих настроек конфигурации на ту же пару <ключ и значение>, пожалуйста, дайте мне знать.
5. Деминем: Вам решать, как будет храниться конфигурация? Ваш shell script — единственное, что его прочитает?
Ответ №2:
#!/bin/sh
filePath=$1 #XML file path
tagName=$2 #Tag name to fetch values
awk '!/<.*>/' RS="<"$tagName">|</"$tagName">" $filePath
Комментарии:
1. Определение RS довольно причудливое, поскольку переменные подставляются внутри двойных кавычек, поэтому нет причин не включать их в строку, заключенную в кавычки. Если вы хотите быть немного более точным в отношении имен переменных, вы всегда можете заключить их в фигурные скобки, например
RS="<${tagName}>|</${tagName}>'
. Но, несмотря на все это, regex недостаточно для синтаксического анализа XML, потому что он может вкладываться. Например., если вы можете иметь внутри себя тег с тем же именем, этот код завершится ошибкой.