Как извлечь свойства XML с помощью сценариев оболочки? - PullRequest
2 голосов
/ 10 октября 2008

Я уже извлек тег из исходного документа, используя grep, но теперь я не могу понять, как легко извлечь свойства из строки. Также я хочу избежать использования любых программ, которые обычно не присутствуют при стандартной установке.

$tag='<img src="http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg" title="Don't we all." alt="Barrel - Part 1" />'  

Мне нужно получить следующие переменные

$src="http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg"
$title="Don't we all."
$alt="Barrel - Part 1"

Ответы [ 4 ]

4 голосов
/ 10 октября 2008

Вы можете использовать xmlstarlet . Тогда вам даже не нужно извлекать элемент самостоятельно:

$ echo $tag|xmlstarlet sel -t --value-of '//img/@src'
http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg

Вы даже можете превратить это в функцию

$ get_attribute() {
  echo $1 | xmlstarlet sel -t -o "&quot;" -v $2 -o "&quot;"
  }
$ src=get_attribute $tag '//img/@src'

Если вы не хотите повторно анализировать документ несколько раз, вы также можете сделать:

$ get_values() {
   eval file=\${$#}
   eval $#=    
   cmd="xmlstarlet sel "
   for arg in $@
   do
      if [ -n $arg ]
      then
        var=${arg%%\=*}
        expr=${arg#*=}
        cmd+=" -t -o \"$var=&quot;\" -v $expr -o \"&quot;\" -n"
      fi
   done
   eval $cmd $file
  }
$ eval $(get_values src='//img/@src' title='//img/@title' your_file.xml)
$ echo $src
http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg
$ echo $title
Don't we all.

Я уверен, что есть лучший способ удалить последний аргумент функции оболочки, но я этого не знаю.

1 голос
/ 10 октября 2008

Я согласился с предложением Дакракота использовать sed, хотя я бы предпочел, чтобы он дал мне пример кода

src=`echo $tag | sed 's/.*src=["]\(.*\)["] title=["]\(.*\)["] alt=["]\(.*\)["].*/\1/'`    
title=`echo $tag | sed 's/.*src=["]\(.*\)["] title=["]\(.*\)["] alt=["]\(.*\)["].*/\2/'`  
alt=`echo $tag | sed 's/.*src=["]\(.*\)["] title=["]\(.*\)["] alt=["]\(.*\)["].*/\3/'`
0 голосов
/ 08 мая 2013

Так как это снова всплыло, теперь у меня есть Xidel , который имеет 2 функции, которые делают эту задачу тривиальной:

  • сопоставление с образцом в xml

  • экспорт всех соответствующих переменных в оболочку

Таким образом, это становится одной строкой:

eval $(xidel "$tag" -e '<img src="{$src}" title="{$title}" alt="{$alt}"/>' --output-format bash)
0 голосов
/ 04 июля 2010

Если xmlstarlet доступен при стандартной установке и последовательность src-title-alt не меняется, вы также можете использовать следующий код:

tag='<img src="http://imgs.xkcd.com/comics/barrel_cropped_(1).jpg" title="Don'"'"'t we all." alt="Barrel - Part 1" />'
xmlstarlet sel -T -t -m "/img" -m "@*" -v '.' -n <<< "$tag"
IFS=$'\n'
array=( $(xmlstarlet sel -T -t -m "/img" -m "@*" -v '.' -n <<< "$tag") )
src="${array[0]}"
title="${array[1]}"
alt="${array[2]}"

printf "%s\n" "src: $src" "title: $title" "alt: $alt"
...