Im Idealfall möchte ich Folgendes tun können:
cat xhtmlfile.xhtml |
getElementViaXPath --path='/html/head/title' |
sed -e 's%(^<title>|</title>$)%%g' > titleOfXHTMLPage.txt
Dies ist eigentlich nur eine Erklärung von Yuzems Antwort, aber ich hatte nicht das Gefühl, dass jemand anders so viel bearbeiten sollte, und Kommentare erlauben keine Formatierung, also ...
rdom () { local IFS=\> ; read -d \< E C ;}
Nennen wir das "read_dom" anstelle von "rdom", platzieren Sie es ein wenig und verwenden Sie längere Variablen:
read_dom () {
local IFS=\>
read -d \< ENTITY CONTENT
}
Okay, es definiert eine Funktion namens read_dom. In der ersten Zeile wird IFS (das Eingabefeldtrennzeichen) für diese Funktion als lokal festgelegt und in> geändert. Das heißt, wenn Sie Daten lesen, anstatt sie automatisch nach Leerzeichen, Tabulatoren oder Zeilenumbrüchen aufzuteilen, werden sie nach ">" aufgeteilt. In der nächsten Zeile wird angegeben, dass die Eingabe von stdin gelesen werden soll. Anstatt an einer neuen Zeile anzuhalten, halten Sie an, wenn Sie ein <-Zeichen sehen (das -d für das Trennzeichen). Was gelesen wird, wird dann über das IFS aufgeteilt und der Variablen ENTITY und CONTENT zugeordnet. Also nimm folgendes:
<tag>value</tag>
Beim ersten Aufruf von read_dom
Wird eine leere Zeichenfolge abgerufen (da das '<' das erste Zeichen ist). Das wird von IFS in nur '' aufgeteilt, da es kein '>' Zeichen gibt. Read weist dann beiden Variablen eine leere Zeichenfolge zu. Der zweite Aufruf erhält den String 'tag> value'. Das wird dann vom IFS in die beiden Felder 'Tag' und 'Wert' aufgeteilt. Lesen Sie dann ordnet die Variablen wie: ENTITY=tag
Und CONTENT=value
. Der dritte Aufruf erhält den String '/ tag>'. Das wird vom IFS in die beiden Felder '/ tag' und '' aufgeteilt. Lesen Sie dann ordnet die Variablen wie: ENTITY=/tag
Und CONTENT=
. Der vierte Aufruf gibt einen Status ungleich Null zurück, da das Dateiende erreicht ist.
Jetzt hat seine while-Schleife ein bisschen aufgeräumt, um den obigen Werten zu entsprechen:
while read_dom; do
if [[ $ENTITY = "title" ]]; then
echo $CONTENT
exit
fi
done < xhtmlfile.xhtml > titleOfXHTMLPage.txt
In der ersten Zeile steht nur: "Während die Funktion read_dom den Status Null zurückgibt, gehen Sie wie folgt vor." In der zweiten Zeile wird überprüft, ob das Objekt, das wir gerade gesehen haben, "title" ist. Die nächste Zeile gibt den Inhalt des Tags wieder. Die vier Zeilen enden. Wenn es nicht das Titelelement war, wird die Schleife in der sechsten Zeile wiederholt. Wir leiten "xhtmlfile.xhtml" in die Standardeingabe um (für die Funktion read_dom
) Und leiten die Standardausgabe in "titleOfXHTMLPage.txt" um (das Echo von früher in der Schleife).
Geben Sie nun Folgendes an (ähnlich wie beim Auflisten eines Buckets in S3) für input.xml
:
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>sth-items</Name>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>[email protected]</Key>
<LastModified>2011-07-25T22:23:04.000Z</LastModified>
<ETag>"0032a28286680abee71aed5d059c6a09"</ETag>
<Size>1785</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
</ListBucketResult>
und die folgende Schleife:
while read_dom; do
echo "$ENTITY => $CONTENT"
done < input.xml
Du solltest bekommen:
=>
ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/" =>
Name => sth-items
/Name =>
IsTruncated => false
/IsTruncated =>
Contents =>
Key => [email protected]
/Key =>
LastModified => 2011-07-25T22:23:04.000Z
/LastModified =>
ETag => "0032a28286680abee71aed5d059c6a09"
/ETag =>
Size => 1785
/Size =>
StorageClass => STANDARD
/StorageClass =>
/Contents =>
Wenn wir also eine while
-Schleife wie die von Yuzem schreiben würden:
while read_dom; do
if [[ $ENTITY = "Key" ]] ; then
echo $CONTENT
fi
done < input.xml
Wir würden eine Liste aller Dateien im S3-Bucket erhalten.
[~ # ~] edit [~ # ~] Wenn aus irgendeinem Grund local IFS=\>
nicht funktioniert und Sie es global einstellen , sollten Sie es am Ende der Funktion zurücksetzen wie:
read_dom () {
ORIGINAL_IFS=$IFS
IFS=\>
read -d \< ENTITY CONTENT
IFS=$ORIGINAL_IFS
}
Andernfalls werden alle Zeilen, die Sie später im Skript aufteilen, durcheinander gebracht.
EDIT 2 Zum Aufteilen von Attributnamen/Wert-Paaren können Sie die Funktion read_dom()
folgendermaßen erweitern:
read_dom () {
local IFS=\>
read -d \< ENTITY CONTENT
local ret=$?
TAG_NAME=${ENTITY%% *}
ATTRIBUTES=${ENTITY#* }
return $ret
}
Dann schreiben Sie Ihre Funktion, um die gewünschten Daten zu analysieren:
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
}
Dann, während Sie read_dom
Aufrufen parse_dom
:
while read_dom; do
parse_dom
done
Geben Sie dann das folgende Beispiel-Markup an:
<example>
<bar size="bar_size" type="metal">bars content</bar>
<foo size="1789" type="unknown">foos content</foo>
</example>
Sie sollten diese Ausgabe erhalten:
$ cat example.xml | ./bash_xml.sh
bar type is: metal
foo size is: 1789
EDIT 3 Ein anderer Benutzer gab an, Probleme mit FreeBSD zu haben, und schlug vor, den Exit-Status vor dem Lesen zu speichern und ihn an zurückzugeben das Ende von read_dom wie:
read_dom () {
local IFS=\>
read -d \< ENTITY CONTENT
local RET=$?
TAG_NAME=${ENTITY%% *}
ATTRIBUTES=${ENTITY#* }
return $RET
}
Ich sehe keinen Grund, warum das nicht funktionieren sollte
Das geht ganz einfach mit bash. Sie müssen nur diese Funktion hinzufügen:
rdom () { local IFS=\> ; read -d \< E C ;}
Jetzt können Sie rdom wie read verwenden, aber für HTML-Dokumente. Beim Aufruf von rdom wird das Element der Variablen E und der Inhalt der Variable C zugewiesen.
Zum Beispiel, um das zu tun, was Sie tun wollten:
while rdom; do
if [[ $E = title ]]; then
echo $C
exit
fi
done < xhtmlfile.xhtml > titleOfXHTMLPage.txt
Befehlszeilentools, die über Shell-Skripte aufgerufen werden können, umfassen:
Ich verwende auch xmllint und xsltproc mit kleinen XSL-Transformationsskripten, um die XML-Verarbeitung über die Befehlszeile oder in Shell-Skripten durchzuführen.
Sie können das Dienstprogramm xpath verwenden. Es wird mit dem Perl XML-XPath-Paket installiert.
Verwendung:
/usr/bin/xpath [filename] query
oder XMLStarlet . Um es auf opensuse zu installieren, benutze:
Sudo zypper install xmlstarlet
oder Versuche cnf xml
auf anderen Plattformen.
Das ist ausreichend ...
xpath xhtmlfile.xhtml '/html/head/title/text()' > titleOfXHTMLPage.txt
Check out XML2 from http://www.ofb.net/~egnor/xml2/ das XML in eine Zeile konvertiert -orientiertes Format.
ausgehend von der Antwort des Chads ist hier die KOMPLETTE Arbeitslösung zum Parsen von UML mit korrekter Behandlung von Kommentaren mit nur 2 kleinen Funktionen (mehr als 2 bu können Sie sie alle mischen). Ich sage nicht, dass Chads eine überhaupt nicht funktioniert hat, aber es gab zu viele Probleme mit schlecht formatierten XML-Dateien: Man muss also etwas schwieriger sein, mit Kommentaren und fehlplatzierten Leerzeichen/CR/TAB/etc umzugehen.
Der Zweck dieser Antwort ist es, jedem, der UML ohne komplexe Werkzeuge mit Perl analysieren möchte, sofort einsatzbereite Bash-Funktionen zu bieten python oder irgendetwas anderes. Was mich betrifft, ich Ich kann weder cpan noch Perl-Module für das alte Betriebssystem installieren, an dem ich arbeite, und python ist nicht verfügbar.
Zunächst eine Definition der in diesem Beitrag verwendeten UML-Wörter:
<!-- comment... -->
<tag attribute="value">content...</tag>
EDIT: aktualisierte Funktionen, mit Handle von:
xml_read_dom() {
# https://stackoverflow.com/questions/893585/how-to-parse-xml-in-bash
local ENTITY IFS=\>
if $ITSACOMMENT; then
read -d \< COMMENTS
COMMENTS="$(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
}
und der zweite:
xml_read() {
# https://stackoverflow.com/questions/893585/how-to-parse-xml-in-bash
ITSACOMMENT=false
local MULTIPLE_ATTR LIGHT FORCE_PRINT XAPPLY XCOMMAND XATTRIBUTE GETCONTENT fileXml tag attributes attribute tag2print TAGPRINTED attribute2print XAPPLIED_COLOR PROSTPROCESS USAGE
local TMP LOG LOGG
LIGHT=false
FORCE_PRINT=false
XAPPLY=false
MULTIPLE_ATTR=false
XAPPLIED_COLOR=g
TAGPRINTED=false
GETCONTENT=false
PROSTPROCESS=cat
Debug=${Debug:-false}
TMP=/tmp/xml_read.$RANDOM
USAGE="${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=$1
tag=$2
(( $# > 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/[^\"]*([\"][^\"]*[\"][,]?)[^\"]*/\1 /g' $TMP
. $TMP
rm -f $TMP
fi
unset ITSACOMMENT
}
und zuletzt die Funktionen rtrim, trim und echo2 (to stderr):
rtrim() {
local [email protected]
var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters
echo -n "$var"
}
trim() {
local [email protected]
var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters
echo -n "$var"
}
echo2() { echo -e "[email protected]" 1>&2; }
oh und du brauchst ein paar nette dynamische Variablen zum Kolorieren, die zuerst definiert und auch exportiert werden:
set -a
TERM=xterm-256color
case ${UNAME} in
AIX|SunOS)
M=$(${print} '\033[1;35m')
m=$(${print} '\033[0;35m')
END=$(${print} '\033[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} '\033[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} "\033[38;5;${colorNums[$num]}m"); NN[$num]=$(${print} "\033[48;5;${colorNums[$num]}m"); done
# piped decolorization:
DECOLORIZE='eval sed "s,${END}\[[0-9;]*[m|K],,g"'
Entweder Sie wissen, wie Sie Funktionen erstellen und über FPATH (ksh) oder eine Emulation von FPATH (bash) laden.
Wenn nicht, kopieren Sie einfach alles in die Befehlszeile.
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
Im Debug-Modus (-d) werden Kommentare und analysierte Attribute nach stderr gedruckt
Ein anderes Kommandozeilenwerkzeug ist mein neues Xidel . Es unterstützt auch XPath 2 und XQuery, im Gegensatz zu dem bereits erwähnten xpath/xmlstarlet.
Der Titel kann wie folgt gelesen werden:
xidel xhtmlfile.xhtml -e /html/head/title > titleOfXHTMLPage.txt
Und es hat auch eine coole Funktion, um mehrere Variablen nach Bash zu exportieren. Beispielsweise
eval $(xidel xhtmlfile.xhtml -e 'title := //title, imgcount := count(//img)' --output-format bash )
setzt $title
zum Titel und $imgcount
auf die Anzahl der Bilder in der Datei, die so flexibel sein sollte, wie sie direkt in bash zu analysieren.
Mir ist kein reines Shell-XML-Parsing-Tool bekannt. Sie benötigen also höchstwahrscheinlich ein Tool, das in einer anderen Sprache geschrieben ist.
Mein XML :: Twig Perl-Modul enthält ein solches Tool: xml_grep
, wo würdest du wahrscheinlich schreiben was du willst als xml_grep -t '/html/head/title' xhtmlfile.xhtml > titleOfXHTMLPage.txt
(das -t
Option gibt Ihnen das Ergebnis als Text anstelle von xml)
Es gibt zwar einige vorgefertigte Konsolendienstprogramme, die möglicherweise das tun, was Sie wollen, aber in einer universellen Programmiersprache wie Python = die Sie einfach erweitern und an Ihre Bedürfnisse anpassen können.
Hier ist ein python Skript, das lxml
zum Parsen verwendet - es verwendet den Namen einer Datei oder einer URL als ersten Parameter, einen XPath-Ausdruck als zweiten Parameter und gibt die Zeichenfolgen/Knoten aus, die dem angegebenen Ausdruck entsprechen.
#!/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
kann mit pip install lxml
installiert werden. Auf Ubuntu können Sie Sudo apt install python-lxml
verwenden.
python xpath.py myfile.xml "//mynode"
lxml
akzeptiert auch eine URL als Eingabe:
python xpath.py http://www.feedforall.com/sample.xml "//link"
Hinweis : Wenn Ihre XML einen Standardnamensraum ohne Präfix hat (z. B.
xmlns=http://abc...
), müssen Sie diep
verwenden. Präfix (bereitgestellt durch den 'Hack') in Ihren Ausdrücken, z//p:module
, um die Module aus einerpom.xml
-Datei abzurufen. Falls das Präfixp
bereits in Ihrer XML-Datei zugeordnet ist, müssen Sie das Skript ändern, um ein anderes Präfix zu verwenden.
Ein einmaliges Skript, das dem engen Zweck dient, Modulnamen aus einer Apache-Maven-Datei zu extrahieren. Beachten Sie, wie dem Knotennamen (module
) der Standardnamespace {http://maven.Apache.org/POM/4.0.0}
vorangestellt wird:
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)
Nach einigen Recherchen zur Übersetzung der Dateipfade in XML-Dateien zwischen Linux- und Windows-Formaten fand ich interessante Tutorials und Lösungen zu folgenden Themen:
Nun, Sie können das Dienstprogramm xpath verwenden. Ich denke, Perls XML :: Xpath enthält es.
Die Methode von Yuzem kann verbessert werden, indem die Reihenfolge der Zeichen <
Und >
In der Funktion rdom
und den Variablenzuweisungen umgekehrt wird.
rdom () { local IFS=\> ; read -d \< E C ;}
wird:
rdom () { local IFS=\< ; read -d \> C E ;}
Wenn das Parsen nicht so durchgeführt wird, wird das letzte Tag in der XML-Datei nie erreicht. Dies kann problematisch sein, wenn Sie beabsichtigen, eine andere XML-Datei am Ende der while
-Schleife auszugeben.
Dies funktioniert, wenn Sie XML-Attribute wünschen:
$ 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