返回XML元素的内容

时间:2015-02-24 12:18:21

标签: xml bash xpath xml-parsing xmlstarlet

我正在尝试使用xmlstarlet来提取此XML Feed中某些元素的文本:

https://services.boatwizard.com/bridge/events/bc0af0c8-4b47-42b3-9a71-5326775344e0/boats?status=on

我想要提取的其中一个元素是城市名称的文本,该文本嵌入在XML文档中(为清晰起见,不包括某些父元素):

<Location>
<LocationAddress>
<CityName>St Malo</CityName>
<CountryID>FR</CountryID>
<Postcode>35400</Postcode>
</LocationAddress>
</Location>

我正在尝试提取“圣马洛”。

我已将Feed保存到boats.xml,并使用xmlstarlet el -v boats.xml找出正确的XPath名称,该名称似乎是:

ProcessVehicleRemarketingDataArea/VehicleRemarketing/VehicleRemarketingBoatLineItem/Location/LocationAddress/CityName

我正在尝试以下语法来提取文本:

xml sel -t -m "ProcessVehicleRemarketingDataArea/VehicleRemarketing/VehicleRemarketingBoatLineItem/Location/LocationAddress/CityName" -v "." -n boats.xml

尝试了许多不同的语法变体但没有成功。几乎认为它可能是关闭的XML文件?我如何提取“圣马洛”?

2 个答案:

答案 0 :(得分:1)

您提供的链接中的XML在VehicleRemarking标记中声明了一个默认命名空间:

 <VehicleRemarketing xmlns="http://www.starstandard.org/STAR/5" ...>

这意味着您必须使用前缀来声明它,您应该使用该前缀来限定属于该命名空间的XPath表达式的每个步骤:

xml sel -N ns=http://www.starstandard.org/STAR/5 
        -t -m "ProcessVehicleRemarketingDataArea/ns:VehicleRemarketing//ns:CityName" 
        -v "." -n boats.xml

第一个元素不是命名空间的一部分,但ns:VehicleRemarketing及其所有子元素都是。在这种情况下,您也可以只使用//ns:CityName表达式(考虑到您发布的示例 - 它将返回文件中所有 CityName个元素。)

答案 1 :(得分:1)

您实际上不需要模板匹配(-m选项),因为在您的情况下查询非常简单。使用

将您在问题中实际显示的XML文档部分作为输入
$ xml sel -t -v "//CityName" -n boats.xml

将导致

St Malo

如果输入文档实际上有名称空间,请考虑使用

$ xml sel -t -v "//*[local-name() = 'CityName']" -n boats.xml

或者,更好的是,将此命名空间URI与前缀一起声明,请参阅helderarocha的答案。