我有一个像这样的结构的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>
总之,你可以通过用../@*
解决父母孩子的属性。