【问题标题】:Extract value from xml file with namespaces by using xmllint in bash在 bash 中使用 xmllint 从带有命名空间的 xml 文件中提取值
【发布时间】:2017-09-27 10:18:10
【问题描述】:

我需要从这个 xml 中提取名称值(产品查找器):

文件:config.xml

<?xml version="1.0" encoding="utf-8"?>
<widget id="com.abc.app" version="1.3.1" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0" ios-CFBundleVersion="1.3.1.5" android-versionCode="5">
    <name>Product Finder</name>
    <description>
        Description
    </description>
</widget>

我试过了:

mles$ xmllint --xpath "/widget/name/text()" config.xml 
XPath set is empty

这可能是因为我的config.xml 文件有其他命名空间。根据this 问题,我需要手动设置命名空间。所以我试过了:

mles$ xmllint --shell config.xml / > setns x=http://www.w3.org/ns/widgets / > xpath /x:widget/name/text

这个没有输出。使用 xmllint 提取名称值的正确语法是什么?

注意:我已经有一个带有 grep 和 sed 的 solution,但我想使用 xmllint。

【问题讨论】:

  • 我可以用 xmlstarlet 轻松解决这个问题
  • sed 's/xmlns=".*"//g' config.xml | xmllint --xpath '/widget/name/text()' - 虽然我支持赛勒斯的回答 :-)

标签: xml bash xml-namespaces xmllint


【解决方案1】:

请注意,不仅声明默认命名空间的元素驻留在该命名空间中,而且所有没有前缀和没有本地默认命名空间的后代元素都隐式地从祖先继承默认命名空间。这意味着您还需要使用前缀 x 来引用 name 元素,因为它从 widget 继承了默认命名空间:

/ > xpath /x:widget/x:name/text()[1]

【讨论】:

    【解决方案2】:

    您的文件使用命名空间 (xmlns)。为了独立于这些,我建议:

    xmllint --xpath "//*[local-name()='widget']/*[local-name()='name']/text()" config.xml
    

    输出:

    产品查找器

    【讨论】:

      猜你喜欢
      • 2020-06-23
      • 2012-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-27
      相关资源
      最近更新 更多