使用XPATH实现Linux Bash XMLLINT

1yjd4xko  于 2023-03-01  发布在  Linux
关注(0)|答案(4)|浏览(136)

今天我开始学习如何正确地使用xmllint。它似乎没有被很好地覆盖或解释。我计划使用一个单一的语言资源文件来运行我的整个系统。我有一个bash脚本和php页面的混合体,必须从这个语言文件中读取。
目前我在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行获得这个值吗?

piv4azn7

piv4azn71#

如何以特定为目标,然后深入到其子元素
执行此操作的正确XPath表达式为:

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

简单地说:从文档节点开始,到文档元素resources,再到其子元素item,但仅当id属性的值为"index.php"时,再到其子元素description并检索其文本值。
我使用xmlint来验证XML文档,但从来没有使用它来验证路径表达式。在bash shell中(至少在Mac OS中),有一个更简单的工具来计算XPath表达式,称为"xpath":

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

然后,获得以下结果:

Found 1 nodes:
-- NODE --
DESCRIPTION

如果您仍然喜欢xmlint,请按以下方式使用它:

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

默认情况下,--xpath意味着--noout,这会阻止xmlint输出输入的XML文件,为了使输出更具可读性,我将输出重定向到一个文件。

$ cat result.txt 
DESCRIPTION
c3frrgcw

c3frrgcw2#

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

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

pkbketx93#

几分钟前我也遇到了同样的问题,看到了这个帖子。
经过一点黑客我发现以下解决方案来提取城市:

(
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-Path来获取所需的XML标记,然后只返回节点值。

brvekthn

brvekthn4#

如果您的xml文档使用名称空间,那么使用xmlint会很麻烦。
例如,要从一个典型的SMPTE资产Map中提取所有路径,简单地运行//Path/text()会导致"XPath set is empty"。

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

结果:

MER_SHR_C_EN-XX_US-NR_51_LTRT_UHD_ML7_SL4_20160915_OV_00.mxf

对于xml:

<?xml version="1.0" encoding="UTF-8"?>
<AssetMap xmlns="http://www.smpte-ra.org/schemas/429-9/2007/AM">
  <Id>urn:uuid:f49af561-3b6c-439f-a3de-f7366f287c09</Id>
  <AnnotationText>MERIDIAN_SHR_C_EN-XX_US-NR_51_LTRT_UHD_ML7_SL4_20160915_OV</AnnotationText>
  <Creator>Studio Technologies</Creator>
  <VolumeCount>1</VolumeCount>
  <IssueDate>2016-09-15T10:10:50+00:00</IssueDate>
  <Issuer>NETFLIX</Issuer>
  <AssetList>
    <Asset>
      <Id>urn:uuid:66fae909-5690-4f9f-b43f-12d302cb7857</Id>
      <ChunkList>
        <Chunk>
          <Path>MER_SHR_C_EN-XX_US-NR_51_LTRT_UHD_ML7_SL4_20160915_OV_00.mxf</Path>
          <VolumeIndex>1</VolumeIndex>
          <Offset>0</Offset>
          <Length>106753518178</Length>
        </Chunk>
      </ChunkList>
    </Asset>
  </AssetList>
</AssetMap>

相关问题