Comment analyser XML en Bash?

idéalement, ce que je voudrais pouvoir faire est:

cat xhtmlfile.xhtml |
getElementViaXPath --path='/html/head/title' |
sed -e 's%(^<title>|</title>$)%%g' > titleOfXHTMLPage.txt
109
demandé sur Steven Penny 2009-05-21 19:36:53

14 réponses

ce n'est vraiment qu'une explication de la réponse de Yuzem , mais je n'ai pas l'impression que ce beaucoup d'édition devrait être fait à quelqu'un d'autre, et les commentaires ne permettent pas le formatage, donc...

rdom () { local IFS=\> ; read -d \< E C ;}

appelons cela "read_dom" au lieu de "rdom", espacez-le un peu et utilisez des variables plus longues:

read_dom () {
    local IFS=\>
    read -d \< ENTITY CONTENT
}

Ok donc il définit une fonction appelée read_dom. La première ligne rend IFS (le séparateur de champ d'entrée) local pour cette fonction et le change >. Cela signifie que lorsque vous lisez des données au lieu d'être automatiquement divisé sur l'espace, l'onglet ou les nouvelles lignes il obtient divisé sur'>'. La ligne suivante dit de lire les entrées de stdin, et au lieu de s'arrêter à une nouvelle ligne, arrêtez quand vous voyez un caractère ' < ' (le-D pour le drapeau de délimiteur). Ce qui est lu est ensuite divisé en utilisant L'IFS et assigné à la variable ENTITY et CONTENT. Prenez donc la suivante:

<tag>value</tag>

le premier appel à read_dom obtenir une chaîne vide (depuis le '<' est le premier caractère). Cela est divisé par si en juste ", puisqu'il n'y a pas de caractère'>'. Read assigne alors une chaîne vide aux deux variables. Le second appel reçoit la chaîne 'tag>value'. Cela est ensuite divisé par les Fi en deux champs 'tag' et 'value'. Read assigne alors les variables comme: ENTITY=tag et CONTENT=value . Le troisième appel reçoit la chaîne ' / tag>'. Cela est divisé par les Fi en deux champs '/tag' et ". Lire attribue le variables comme: ENTITY=/tag et CONTENT= . Le quatrième appel retournera un statut non-zéro parce que nous avons atteint la fin du fichier.

maintenant sa boucle while nettoyé un peu pour correspondre à ce qui précède:

while read_dom; do
    if [[ $ENTITY = "title" ]]; then
        echo $CONTENT
        exit
    fi
done < xhtmlfile.xhtml > titleOfXHTMLPage.txt

la première ligne dit simplement, " tandis que la fonction read_dom renvoie un statut zéro, faites ce qui suit."La deuxième ligne vérifie si l'entité que nous venons de voir est "title". La ligne suivante fait écho au contenu de la balise. Les sorties à quatre lignes. Si c' ce n'était pas l'entité titre puis la boucle se répète sur la sixième ligne. Nous redirigeons " xhtmlfile.xhtml" en entrée standard (pour la fonction read_dom ) et rediriger la sortie standard vers " titleOfXHTMLPage.txt" (l'écho de plus tôt dans la boucle).

maintenant donné ce qui suit (similaire à ce que vous obtenez de l'inscription d'un seau sur S3) pour input.xml :

<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Name>sth-items</Name>
  <IsTruncated>false</IsTruncated>
  <Contents>
    <Key>item-apple-iso@2x.png</Key>
    <LastModified>2011-07-25T22:23:04.000Z</LastModified>
    <ETag>&quot;0032a28286680abee71aed5d059c6a09&quot;</ETag>
    <Size>1785</Size>
    <StorageClass>STANDARD</StorageClass>
  </Contents>
</ListBucketResult>

et la boucle suivante:

while read_dom; do
    echo "$ENTITY => $CONTENT"
done < input.xml

vous devriez obtenir:

 => 
ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/" => 
Name => sth-items
/Name => 
IsTruncated => false
/IsTruncated => 
Contents => 
Key => item-apple-iso@2x.png
/Key => 
LastModified => 2011-07-25T22:23:04.000Z
/LastModified => 
ETag => &quot;0032a28286680abee71aed5d059c6a09&quot;
/ETag => 
Size => 1785
/Size => 
StorageClass => STANDARD
/StorageClass => 
/Contents => 

donc si nous avons écrit une while boucle comme Yuzem:

while read_dom; do
    if [[ $ENTITY = "Key" ]] ; then
        echo $CONTENT
    fi
done < input.xml

nous obtenions une liste de tous les fichiers dans le seau S3.

EDIT Si pour une raison quelconque local IFS=\> ne fonctionne pas pour vous et que vous le définissez globalement, vous devriez le réinitialiser à la fin de la fonction comme:

read_dom () {
    ORIGINAL_IFS=$IFS
    IFS=\>
    read -d \< ENTITY CONTENT
    IFS=$ORIGINAL_IFS
}

dans le cas contraire, toute division de ligne que vous ferez plus tard dans le script sera gâcher.

EDIT 2 Pour séparer les paires nom/valeur d'un attribut, vous pouvez augmenter le read_dom() comme suit:

read_dom () {
    local IFS=\>
    read -d \< ENTITY CONTENT
    local ret=$?
    TAG_NAME=${ENTITY%% *}
    ATTRIBUTES=${ENTITY#* }
    return $ret
}

alors écrivez votre fonction pour analyser et obtenir les données que vous voulez comme ceci:

parse_dom () {
    if [[ $TAG_NAME = "foo" ]] ; then
        eval local $ATTRIBUTES
        echo "foo size is: $size"
    elif [[ $TAG_NAME = "bar" ]] ; then
        eval local $ATTRIBUTES
        echo "bar type is: $type"
    fi
}

alors que vous read_dom appelez parse_dom :

while read_dom; do
    parse_dom
done

donne alors l'exemple de balisage suivant:

<example>
  <bar size="bar_size" type="metal">bars content</bar>
  <foo size="1789" type="unknown">foos content</foo>
</example>

vous devriez obtenir cette sortie:

$ cat example.xml | ./bash_xml.sh 
bar type is: metal
foo size is: 1789

MODIFIER 3 l'autre utilisateur , a déclaré qu'ils étaient d'avoir des problèmes avec elle dans FreeBSD et proposé d'enregistrer le statut de sortie de le lire et de le retourner à la fin de read_dom comme:

read_dom () {
    local IFS=\>
    read -d \< ENTITY CONTENT
    local RET=$?
    TAG_NAME=${ENTITY%% *}
    ATTRIBUTES=${ENTITY#* }
    return $RET
}

je ne vois pas pourquoi cela ne fonctionnerait pas

130
répondu chad 2017-05-23 11:55:10

Vous pouvez le faire très facilement en utilisant seulement bash. Vous n'avez qu'à ajouter cette fonction:

rdom () { local IFS=\> ; read -d \< E C ;}

Maintenant, vous pouvez utiliser rdom comme lire mais pour les documents html. Lorsqu'il est appelé Radom assignera l'élément à la variable E et le contenu à var C.

par exemple, pour faire ce que vous vouliez faire:

while rdom; do
    if [[ $E = title ]]; then
        echo $C
        exit
    fi
done < xhtmlfile.xhtml > titleOfXHTMLPage.txt
57
répondu Yuzem 2010-04-09 14:13:13

les outils en ligne de commande qui peuvent être appelés à partir de scripts shell comprennent:

  • 4xpath -wrapper en ligne de commande autour du 4suite package
  • XMLStarlet
  • xpath - de ligne de commande wrapper autour de Perl XPath bibliothèque
  • Xidel - fonctionne avec des URLs ainsi que des fichiers. Fonctionne également avec JSON

j'utilise aussi xmllint et xsltproc avec de petits scripts de transformation XSL pour faire le traitement XML à partir de la ligne de commande ou dans des scripts shell.

48
répondu Nat 2017-01-10 21:10:38

vous pouvez utiliser l'utilitaire xpath. Il est installé avec le paquet Perl XML-XPath.

Utilisation:

/usr/bin/xpath [filename] query

ou XMLStarlet . Pour l'installer sur opensuse utiliser:

sudo zypper install xmlstarlet

ou essayez cnf xml sur d'autres plateformes.

17
répondu Grisha 2012-07-06 16:19:39

cela suffit...

xpath xhtmlfile.xhtml '/html/head/title/text()' > titleOfXHTMLPage.txt
6
répondu teknopaul 2015-01-05 10:33:58

Je ne suis pas au courant de l'existence d'un outil D'analyse XML pur shell. Ainsi, vous aurez très probablement besoin d'un outil écrit en une autre langue.

My XML:: Twig Perl module vient avec un tel outil: xml_grep , où vous écririez probablement ce que vous voulez comme xml_grep -t '/html/head/title' xhtmlfile.xhtml > titleOfXHTMLPage.txt (l'option -t vous donne le résultat sous forme de texte au lieu de xml)

4
répondu mirod 2009-05-21 15:43:58

Check out XML2 from http://www.ofb.net/~egnor/ xml2 / qui convertit XML en format orienté ligne.

4
répondu simon04 2009-11-07 15:31:22

un autre outil en ligne de commande est mon nouveau Xidel . Il supporte également XPath 2 et XQuery, contrairement au xpath/xmlstarlet déjà mentionné.

le titre se lit comme suit:

xidel xhtmlfile.xhtml -e /html/head/title > titleOfXHTMLPage.txt

et il a également une caractéristique cool pour exporter des variables multiples à bash. Par exemple

eval $(xidel xhtmlfile.xhtml -e 'title := //title, imgcount := count(//img)' --output-format bash )

fixe $title au titre et $imgcount au nombre d'images dans le fichier, qui devrait être comme flexible comme le parsing directement dans bash.

4
répondu BeniBela 2013-03-27 00:27:21

a partir de la réponse du Tchad, voici la solution de travail complète pour analyser UML, avec la gestion propper des commentaires, avec seulement 2 petites fonctions (plus de 2 bu vous pouvez les mélanger tous). Je ne dis pas que celui de chad n'a pas fonctionné du tout, mais il avait trop de problèmes avec les fichiers XML mal formatés: il faut donc être un peu plus délicat pour gérer les commentaires et les espaces mal placés/CR/TAB/etc.

le but de cette réponse est de donner prêt-2-usage, hors de la boîte bash fonctions à toute personne ayant besoin d'analyser UML sans outils complexes en utilisant perl, python ou autre chose. Quant à moi, Je ne peux pas installer cpan, ni les modules perl pour L'ancien OS de production sur lequel je travaille, et python n'est pas disponible.

tout D'abord, une définition des mots UML utilisés dans ce post:

<!-- comment... -->
<tag attribute="value">content...</tag>

EDIT: mise à jour des fonctions, avec poignée de:

  • Websphere xml (attributs xmi et xmlns))
  • doit avoir un terminal compatible avec 256 couleurs
  • 24 nuances de gris
  • compatibilité ajoutée pour IBM AIX bash 3.2.16 (1)

les fonctions, d'abord est le xml_read_dom qui est appelé récursivement par xml_read:

xml_read_dom() {
# /q/how-to-parse-xml-in-bash-38700/"$(rtrim "${COMMENTS}")"
  return 0
else
  read -d \< ENTITY CONTENT
  CR=$?
  [ "x${ENTITY:0:1}x" == "x/x" ] && return 0
  TAG_NAME=${ENTITY%%[[:space:]]*}
  [ "x${TAG_NAME}x" == "x?xmlx" ] && TAG_NAME=xml
  TAG_NAME=${TAG_NAME%%:*}
  ATTRIBUTES=${ENTITY#*[[:space:]]}
  ATTRIBUTES="${ATTRIBUTES//xmi:/}"
  ATTRIBUTES="${ATTRIBUTES//xmlns:/}"
fi

# when comments sticks to !-- :
[ "x${TAG_NAME:0:3}x" == "x!--x" ] && COMMENTS="${TAG_NAME:3} ${ATTRIBUTES}" && ITSACOMMENT=true && return 0

# http://tldp.org/LDP/abs/html/string-manipulation.html
# INFO: oh wait it doesn't work on IBM AIX bash 3.2.16(1):
# [ "x${ATTRIBUTES:(-1):1}x" == "x/x" -o "x${ATTRIBUTES:(-1):1}x" == "x?x" ] && ATTRIBUTES="${ATTRIBUTES:0:(-1)}"
[ "x${ATTRIBUTES:${#ATTRIBUTES} -1:1}x" == "x/x" -o "x${ATTRIBUTES:${#ATTRIBUTES} -1:1}x" == "x?x" ] && ATTRIBUTES="${ATTRIBUTES:0:${#ATTRIBUTES} -1}"
return $CR
}

et le second:

xml_read() {
# /q/how-to-parse-xml-in-bash-38700/"${C}${FUNCNAME}${c} [-cdlp] [-x command <-a attribute>] <file.xml> [tag | \"any\"] [attributes .. | \"content\"]
${nn[2]}  -c = NOCOLOR${END}
${nn[2]}  -d = Debug${END}
${nn[2]}  -l = LIGHT (no \"attribute=\" printed)${END}
${nn[2]}  -p = FORCE PRINT (when no attributes given)${END}
${nn[2]}  -x = apply a command on an attribute and print the result instead of the former value, in green color${END}
${nn[1]}  (no attribute given will load their values into your shell; use '-p' to print them as well)${END}"

! (($#)) && echo2 "$USAGE" && return 99
(( $# < 2 )) && ERROR nbaram 2 0 && return 99
# getopts:
while getopts :cdlpx:a: _OPT 2>/dev/null
do
{
  case ${_OPT} in
    c) PROSTPROCESS="${DECOLORIZE}" ;;
    d) local Debug=true ;;
    l) LIGHT=true; XAPPLIED_COLOR=END ;;
    p) FORCE_PRINT=true ;;
    x) XAPPLY=true; XCOMMAND="${OPTARG}" ;;
    a) XATTRIBUTE="${OPTARG}" ;;
    *) _NOARGS="${_NOARGS}${_NOARGS+, }-${OPTARG}" ;;
  esac
}
done
shift $((OPTIND - 1))
unset _OPT OPTARG OPTIND
[ "X${_NOARGS}" != "X" ] && ERROR param "${_NOARGS}" 0

fileXml=
tag=
(( $# > 2 )) && shift 2 && attributes=$*
(( $# > 1 )) && MULTIPLE_ATTR=true

[ -d "${fileXml}" -o ! -s "${fileXml}" ] && ERROR empty "${fileXml}" 0 && return 1
$XAPPLY && $MULTIPLE_ATTR && [ -z "${XATTRIBUTE}" ] && ERROR param "-x command " 0 && return 2
# nb attributes == 1 because $MULTIPLE_ATTR is false
[ "${attributes}" == "content" ] && GETCONTENT=true

while xml_read_dom; do
  # (( CR != 0 )) && break
  (( PIPESTATUS[1] != 0 )) && break

  if $ITSACOMMENT; then
    # oh wait it doesn't work on IBM AIX bash 3.2.16(1):
    # if [ "x${COMMENTS:(-2):2}x" == "x--x" ]; then COMMENTS="${COMMENTS:0:(-2)}" && ITSACOMMENT=false
    # elif [ "x${COMMENTS:(-3):3}x" == "x-->x" ]; then COMMENTS="${COMMENTS:0:(-3)}" && ITSACOMMENT=false
    if [ "x${COMMENTS:${#COMMENTS} - 2:2}x" == "x--x" ]; then COMMENTS="${COMMENTS:0:${#COMMENTS} - 2}" && ITSACOMMENT=false
    elif [ "x${COMMENTS:${#COMMENTS} - 3:3}x" == "x-->x" ]; then COMMENTS="${COMMENTS:0:${#COMMENTS} - 3}" && ITSACOMMENT=false
    fi
    $Debug && echo2 "${N}${COMMENTS}${END}"
  elif test "${TAG_NAME}"; then
    if [ "x${TAG_NAME}x" == "x${tag}x" -o "x${tag}x" == "xanyx" ]; then
      if $GETCONTENT; then
        CONTENT="$(trim "${CONTENT}")"
        test ${CONTENT} && echo "${CONTENT}"
      else
        # eval local $ATTRIBUTES => eval test "\"$${attribute}\"" will be true for matching attributes
        eval local $ATTRIBUTES
        $Debug && (echo2 "${m}${TAG_NAME}: ${M}$ATTRIBUTES${END}"; test ${CONTENT} && echo2 "${m}CONTENT=${M}$CONTENT${END}")
        if test "${attributes}"; then
          if $MULTIPLE_ATTR; then
            # we don't print "tag: attr=x ..." for a tag passed as argument: it's usefull only for "any" tags so then we print the matching tags found
            ! $LIGHT && [ "x${tag}x" == "xanyx" ] && tag2print="${g6}${TAG_NAME}: "
            for attribute in ${attributes}; do
              ! $LIGHT && attribute2print="${g10}${attribute}${g6}=${g14}"
              if eval test "\"$${attribute}\""; then
                test "${tag2print}" && ${print} "${tag2print}"
                TAGPRINTED=true; unset tag2print
                if [ "$XAPPLY" == "true" -a "${attribute}" == "${XATTRIBUTE}" ]; then
                  eval ${print} "%s%s\ " "${attribute2print}" "${${XAPPLIED_COLOR}}\"$($XCOMMAND $${attribute})\"${END}" && eval unset ${attribute}
                else
                  eval ${print} "%s%s\ " "${attribute2print}" "\"$${attribute}\"" && eval unset ${attribute}
                fi
              fi
            done
            # this trick prints a CR only if attributes have been printed durint the loop:
            $TAGPRINTED && ${print} "\n" && TAGPRINTED=false
          else
            if eval test "\"$${attributes}\""; then
              if $XAPPLY; then
                eval echo "${g}$($XCOMMAND $${attributes})" && eval unset ${attributes}
              else
                eval echo "$${attributes}" && eval unset ${attributes}
              fi
            fi
          fi
        else
          echo eval $ATTRIBUTES >>$TMP
        fi
      fi
    fi
  fi
  unset CR TAG_NAME ATTRIBUTES CONTENT COMMENTS
done < "${fileXml}" | ${PROSTPROCESS}
# http://mywiki.wooledge.org/BashFAQ/024
# INFO: I set variables in a "while loop" that's in a pipeline. Why do they disappear? workaround:
if [ -s "$TMP" ]; then
  $FORCE_PRINT && ! $LIGHT && cat $TMP
  # $FORCE_PRINT && $LIGHT && perl -pe 's/[[:space:]].*?=/ /g' $TMP
  $FORCE_PRINT && $LIGHT && sed -r 's/[^\"]*([\"][^\"]*[\"][,]?)[^\"]*/ /g' $TMP
  . $TMP
  rm -f $TMP
fi
unset ITSACOMMENT
}

et enfin, les fonctions rtrim, trim et echo2 (à stderr):

rtrim() {
local var=$@
var="${var%"${var##*[![:space:]]}"}"   # remove trailing whitespace characters
echo -n "$var"
}
trim() {
local var=$@
var="${var#"${var%%[![:space:]]*}"}"   # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}"   # remove trailing whitespace characters
echo -n "$var"
}
echo2() { echo -e "$@" 1>&2; }

colorisation:

oh, et vous aurez besoin de certains soigné colorisation dynamique des variables à définir au premier abord, et exportés, aussi:

set -a
TERM=xterm-256color
case ${UNAME} in
AIX|SunOS)
  M=$(${print} '3[1;35m')
  m=$(${print} '3[0;35m')
  END=$(${print} '3[0m')
;;
*)
  m=$(tput setaf 5)
  M=$(tput setaf 13)
  # END=$(tput sgr0)          # issue on Linux: it can produces ^[(B instead of ^[[0m, more likely when using screenrc
  END=$(${print} '3[0m')
;;
esac
# 24 shades of grey:
for i in $(seq 0 23); do eval g$i="$(${print} \"\033\[38\;5\;$((232 + i))m\")" ; done
# another way of having an array of 5 shades of grey:
declare -a colorNums=(238 240 243 248 254)
for num in 0 1 2 3 4; do nn[$num]=$(${print} "3[38;5;${colorNums[$num]}m"); NN[$num]=$(${print} "3[48;5;${colorNums[$num]}m"); done
# piped decolorization:
DECOLORIZE='eval sed "s,${END}\[[0-9;]*[m|K],,g"'

Comment charger des trucs du genre:

soit vous savez créer des fonctions et les charger via FPATH (ksh) ou une émulation de FPATH (bash)

si ce n'est pas le cas, il suffit de tout copier/coller sur la ligne de commande.

comment il travail:

xml_read [-cdlp] [-x command <-a attribute>] <file.xml> [tag | "any"] [attributes .. | "content"]
  -c = NOCOLOR
  -d = Debug
  -l = LIGHT (no \"attribute=\" printed)
  -p = FORCE PRINT (when no attributes given)
  -x = apply a command on an attribute and print the result instead of the former value, in green color
  (no attribute given will load their values into your shell as $ATTRIBUTE=value; use '-p' to print them as well)

xml_read server.xml title content     # print content between <title></title>
xml_read server.xml Connector port    # print all port values from Connector tags
xml_read server.xml any port          # print all port values from any tags

avec mode de débogage (- d) les commentaires et les attributs parsés sont imprimés sur stderr

4
répondu scavenger 2018-02-01 16:40:37

Eh bien, vous pouvez utiliser l'utilitaire xpath. Je suppose que le XML de perl:: Xpath le contient.

2
répondu alamar 2009-05-21 15:39:23

après quelques recherches pour la traduction entre les formats Linux et Windows des chemins de fichier dans les fichiers XML, j'ai trouvé des tutoriels et des solutions intéressantes sur:

2
répondu user485380 2010-10-24 01:00:37

bien qu'il y ait pas mal d'utilitaires de console prêts à l'emploi qui pourraient faire ce que vous voulez, il vous faudra probablement moins de temps pour écrire quelques lignes de code dans un langage de programmation universel tel que Python que vous pouvez facilement étendre et adapter à vos besoins.

voici un script python qui utilise lxml pour l'analyse - il prend le nom d'un fichier ou D'une URL comme premier paramètre, une expression XPath comme second paramètre et affiche les chaînes/nœuds correspondant à l'expression donnée.

exemple 1

#!/usr/bin/env python
import sys
from lxml import etree

tree = etree.parse(sys.argv[1])
xpath_expression = sys.argv[2]

#  a hack allowing to access the
#  default namespace (if defined) via the 'p:' prefix    
#  E.g. given a default namespaces such as 'xmlns="http://maven.apache.org/POM/4.0.0"'
#  an XPath of '//p:module' will return all the 'module' nodes
ns = tree.getroot().nsmap
if ns.keys() and None in ns:
    ns['p'] = ns.pop(None)
#   end of hack    

for e in tree.xpath(xpath_expression, namespaces=ns):
    if isinstance(e, str):
        print(e)
    else:
        print(e.text and e.text.strip() or etree.tostring(e, pretty_print=True))

lxml peut être installé avec pip install lxml . Sur ubuntu vous pouvez utiliser sudo apt install python-lxml .

Utilisation

python xpath.py myfile.xml "//mynode"

lxml accepte aussi une URL en entrée:

python xpath.py http://www.feedforall.com/sample.xml "//link"

Note : si votre XML a un namespace par défaut sans préfixe (par exemple xmlns=http://abc... ), vous devez utiliser le préfixe p (fourni par le 'hack') dans vos expressions, par exemple //p:module pour obtenir les modules à partir d'un fichier pom.xml . Si le préfixe p est déjà mappé dans votre XML, alors vous devrez modifier le script pour utiliser un autre préfixe.


exemple 2

un script unique qui sert le but étroit de l'extraction les noms de modules d'un fichier Maven apache. Notez comment le nom du noeud ( module ) est préfixé avec l'espace de noms par défaut {http://maven.apache.org/POM/4.0.0} :

pom.xml :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modules>
        <module>cherries</module>
        <module>bananas</module>
        <module>pears</module>
    </modules>
</project>

module_extractor.py :

from lxml import etree
for _, e in etree.iterparse(open("pom.xml"), tag="{http://maven.apache.org/POM/4.0.0}module"):
    print(e.text)
1
répondu ccpizza 2018-05-18 22:19:21
La méthode de Yuzem

peut être améliorée en inversant l'ordre des signes < et > dans la fonction rdom et les assignations variables, de sorte que:

rdom () { local IFS=\> ; read -d \< E C ;}

devient:

rdom () { local IFS=\< ; read -d \> C E ;}

si l'analyse n'est pas faite comme ceci, la dernière balise dans le fichier XML n'est jamais atteinte. Cela peut être problématique si vous avez l'intention de sortir un autre fichier XML à la fin de la boucle while .

0
répondu michaelmeyer 2013-01-24 00:46:44

cela fonctionne si vous voulez des attributs XML:

$ cat alfa.xml
<video server="asdf.com" stream="H264_400.mp4" cdn="limelight"/>

$ sed 's.[^ ]*..;s./>..' alfa.xml > alfa.sh

$ . ./alfa.sh

$ echo "$stream"
H264_400.mp4
0
répondu Steven Penny 2017-01-03 19:34:25