首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Bash中解析XML?

如何在Bash中解析XML?
EN

Stack Overflow用户
提问于 2018-03-12 04:59:58
回答 2查看 0关注 0票数 0

理想情况下,我想要做的是:

代码语言:txt
复制
cat xhtmlfile.xhtml |
getElementViaXPath --path='/html/head/title' |
sed -e 's%(^<title>|</title>$)%%g' > titleOfXHTMLPage.txt
EN

回答 2

Stack Overflow用户

发布于 2018-03-12 13:39:26

给出以下内容input.xml:

代码语言:txt
复制
<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>

和下面的循环:

代码语言:txt
复制
while read_dom; do
    echo "$ENTITY => $CONTENT"
done < input.xml

返回:

代码语言:txt
复制
 => 
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 => 

所以如果我们写了一个while循环:

代码语言:txt
复制
while read_dom; do
    if [[ $ENTITY = "Key" ]] ; then
        echo $CONTENT
    fi
done < input.xml

我们会得到S3桶中所有文件的列表。

如果出于某种原因local IFS=\>对您不起作用,并且您在全局设置它,您应该在函数的末尾重置它,如下所示:

代码语言:txt
复制
read_dom () {
    ORIGINAL_IFS=$IFS
    IFS=\>
    read -d \< ENTITY CONTENT
    IFS=$ORIGINAL_IFS
}

否则,在脚本后面进行的任何行拆分都会被搞砸。

若要拆分属性名称/值对,可以在read_dom()就像这样:

代码语言:txt
复制
read_dom () {
    local IFS=\>
    read -d \< ENTITY CONTENT
    local ret=$?
    TAG_NAME=${ENTITY%% *}
    ATTRIBUTES=${ENTITY#* }
    return $ret
}

然后编写函数来解析和获取所需的数据,如下所示:

代码语言:txt
复制
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
}

那么当你read_dom打电话parse_dom:

代码语言:txt
复制
while read_dom; do
    parse_dom
done

然后给出以下示例标记:

代码语言:txt
复制
<example>
  <bar size="bar_size" type="metal">bars content</bar>
  <foo size="1789" type="unknown">foos content</foo>
</example>

应该得到以下输出:

代码语言:txt
复制
$ cat example.xml | ./bash_xml.sh 
bar type is: metal
foo size is: 1789
票数 0
EN

Stack Overflow用户

发布于 2018-03-12 14:49:33

你只需使用bash就可以很容易地做到这一点。只需添加以下函数:

代码语言:txt
复制
rdom () { local IFS=\> ; read -d \< E C ;}

现在,您可以像Read一样使用rdom,但可以使用html文档。当被调用时,rdom会将元素分配给变量E,将内容分配给var C。

例如,要做您想做的事情:

代码语言:txt
复制
while rdom; do
    if [[ $E = title ]]; then
        echo $C
        exit
    fi
done < xhtmlfile.xhtml > titleOfXHTMLPage.txt
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100003602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档