2014-11-03 69 views
4

今天,我开始学习如何正确使用xmllint。它似乎没有被很好的覆盖或解释。我打算使用单个语言资源文件来运行我的整个系统。我有一个混合的bash脚本和php页面,必须从这个语言文件中读取。使用XPATH的Linux Bash XMLLINT

目前我使用以下格式在我的xml文件en.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 

    <item id="index.php"> 
     <label>LABEL</label> 
     <value>VALUE</value> 
     <description>DESCRIPTION</description> 
    </item> 
    <item id="config.php"> 
     <label>LABEL</label> 
     <value>VALUE</value> 
     <description>DESCRIPTION</description> 
    </item> 

</resources> 

现在我要开始一个bash脚本行应该从XML文件中提取数据值。例如,我想从index.php项目获得DESCRIPTION的值。

我用

xmllint --xpath 'string(//description)' /path/en.xml 

的不同布局,工作,但现在我改变我的XML文件的布局,我失去了对如何最好地针对特定<item>,然后向下钻取到其在bash脚本中的子元素。

有人可以帮助xmllint --xpath线获得这个值吗?

回答

6

如何更好地针对特定的,然后向下钻取到其子元素

正确的XPath表达式来做到这一点:

/resources/item[@id="index.php"]/description/text() 

用简单的英语:从文件开始节点,转到文档元素resources,转到其子节点item,但仅当id属性的值为“index.php”,其子description并检索其文本v ALUE。

我使用xmllint来验证XML文档,但从来没有用于路径表达式。在bash shell(至少与Mac OS)有用于评估XPath表达式,被称为 “的xpath” 一个更简单的工具:

$ xpath en.xml '/resources/item[@id="index.php"]/description/text()' 

然后,获得以下结果:

Found 1 nodes: 
-- NODE -- 
DESCRIPTION 

如果你还是喜欢xmllint,使用下列方式:

$ xmllint --xpath '/resources/item[@id="index.php"]/description/text()' en.xml > result.txt 

默认情况下,--xpath意味着​​,防止xmllint输出任何内容。将输出重定向到一个文件。

$ cat result.txt 
DESCRIPTION 
+0

工程。非常感谢你的时间和考虑 – RootWannaBe 2014-11-03 08:20:03

+0

嗨,您使用的是哪个版本的xmllint?我有'xmllint --version xmllint:使用libxml版本20626 编译时使用:线程树输出推式阅读器模式编写器SAXv1 FTP HTTP DTDValid HTML旧版C14N目录XPath XPointer XInclude Iconv ISO8859X Unicode正则表达式自动化Expr架构Schematron模块调试' t有** - xpath **选项 – 2016-12-22 07:20:34

+0

@ReddySK结果在我用'xmllint:using libxml version 20902'获得的答案中,但实际上并没有报告xmllint本身的版本,而是底层库的版本(最重要的是,libxml)。看起来你有这里描述的问题:http://stackoverflow.com/q/11975862/1987598,但试图让'-xpath'在xmllint中工作是不值得的麻烦:xmllint主要是一个验证工具,不适用于XPath表达式。改为使用您选择的编程语言的XPath库。 – 2016-12-22 11:49:29

0

几分钟前我有同样的问题,看到这篇文章。

黑客攻击了一下后,我发现以下解决方案来提取城市:

(wget 'http://maps.googleapis.com/maps/api/geocode/xml?latlng=53.244921,-2.479539&sensor=true' -O dummy.xml -o /dev/null;xmllint --format --xpath '/GeocodeResponse/result[type = "postal_town"]/address_component[type = "postal_town"]/short_name/node()' dummy.xml) 

你的东东来指定正确的x路以获得所需的XML的标记,然后只返回节点值。

1

我最喜欢的是xmlstarlet,因为它似乎是更强大的比xmllint

xmlstarlet sel -t -v '/resources/item[@id="index.php"]/description/text()' en.xml 
+0

'xmlstarlet'似乎是一个强大的工具,感谢指针! – 2017-03-22 22:18:35

+0

我对这些命令行秘密武器是'xidel',因为它支持xpath2.0和xquery。 'xidel'的唯一弱点是它不能从标准输入读取,因此它不能像xmlstarlet那样使用Unix管道。尽管xmlstarlet具有较少的XML功能,但因为可以管理它而得到补偿。 – ifelsemonkey 2017-03-24 21:15:18