xmlstarlet XPathexpression式select单个结果而不是多个

我有一个像这样的结构的XML文件:

<?xml version="1.0" encoding="UTF-8"?> <hudson> <authorizationStrategy> <roleMap type="globalRoles"> <role name="Employees"> <assignedSIDs> <sid>abc</sid> <sid>bcd</sid> </assignedSIDs> </role> </roleMap> <roleMap type="projectRoles"> <role name="test1" pattern=".*"> <assignedSIDs> <sid>abc</sid> <sid>zxc</sid> </assignedSIDs> </role> <role name="test2" pattern=".*"> <permissions/> <assignedSIDs> <sid>abc</sid> <sid>ghi</sid> </assignedSIDs> </role> <role name="test3" pattern=".*"> <permissions/> <assignedSIDs> <sid>abc</sid> </assignedSIDs> </role> </roleMap> </authorizationStrategy> </hudson> 

以前,我没有给出整个结构和我遇到的xpath解决scheme,没有给出我期望的结果(在我的系统上,但它给了回答我的问题的人)在下面的链接search标签使用XmlStarlet基于子节点值的属性值

正如在那个链接中提到的,我想根据sid标签的值来查找angular色标签名称属性。 例如:如果我searchabc,查询必须返回Employees,test1,test2和test3。

这是我使用的脚本:

 xmlstarlet sel -t -v "//role[.//sid = 'abc']/@name" test.xml 

但它只给了我'员工'。

我正在使用LINUX / bash。 请告诉我,XPATHexpression式中缺less的是什么。

您使用的XPath和xmlstarlet命令,

 xmlstarlet sel -t -v "//role[.//sid = 'abc']/@name" test.xml 

已经导致下面的字符串被返回,

 Employees test1 test2 test3 

按照要求。

您的XPath是正确的; 你的xmlstarlet命令行是正确的。 重新检查你正在使用的文件名和你运行xmlstarlet的目录。 重新检查你在实际环境中如何使用xmlstarlet命令的结果。 在这个你已经发布的简化形式中,预期的结果恰恰是返回的。


更新 :很抱歉听到你仍然卡住了。 我的最后一个想法是发表详细的记录,以证明这个工作应该是可行的,这样你就可以回溯你的步骤,并试着看看你的路径可能会有所不同:

 c:\gd\usr\kjh\proj\try\xml > cat test.xml <?xml version="1.0" encoding="UTF-8"?> <hudson> <authorizationStrategy> <roleMap type="globalRoles"> <role name="Employees"> <assignedSIDs> <sid>abc</sid> <sid>bcd</sid> </assignedSIDs> </role> </roleMap> <roleMap type="projectRoles"> <role name="test1" pattern=".*"> <assignedSIDs> <sid>abc</sid> <sid>zxc</sid> </assignedSIDs> </role> <role name="test2" pattern=".*"> <permissions/> <assignedSIDs> <sid>abc</sid> <sid>ghi</sid> </assignedSIDs> </role> <role name="test3" pattern=".*"> <permissions/> <assignedSIDs> <sid>abc</sid> </assignedSIDs> </role> </roleMap> </authorizationStrategy> </hudson> c:\gd\usr\kjh\proj\try\xml > xmlstarlet sel -t -v "//role[.//sid = 'abc']/@name" test.xml Employees test1 test2 test3 c:\gd\usr\kjh\proj\try\xml > xmlstarlet --version 1.5.0 compiled against libxml2 2.9.1, linked with 20901 compiled against libxslt 1.1.28, linked with 10128 c:\gd\usr\kjh\proj\try\xml > systeminfo | findstr /B /C:"OS Name" /C:"OS Version" OS Name: Microsoft Windows 7 Professional OS Version: 6.1.7601 Service Pack 1 Build 7601 c:\gd\usr\kjh\proj\try\xml > 

最终更新:

OP注意到他的xmlstarlet版本(v1.0.1)比我在上面的成绩单(xmlstarlet v1.5.0)中使用的版本大得多。 升级到最新版本的xmlstarlet解决了这个问题。

如果你不绑定到xmlstarlet尝试使用xmllint否则调整xpath如下所示可能会有所帮助。

 $ xmllint --xpath '//role//sid/../../@name' roles.xml name="Employees" name="Others" 

这个例子的xml文件看起来像

 <?xml version="1.0" ?> <hudson> <authorizationStrategy> <roleMap> <role name="Employees"> <assignedSIDs> <sid>abc</sid> <sid>bcd</sid> </assignedSIDs> </role> <role name="Others"> <assignedSIDs> <sid>abc</sid> <sid>zxc</sid> </assignedSIDs> </role> </roleMap> </authorizationStrategy> </hudson> 

总之,你可以通过用../@*解决父母孩子的属性。