【问题标题】:Selecting an XML subset with Nokogiri使用 Nokogiri 选择 XML 子集
【发布时间】:2021-08-26 15:23:28
【问题描述】:

对于我第一次发现 Nokogiri 和 XML 解析,我需要提取提供 Web 服务的代码项(及其子项)列表。文档如下所示:

<message:Structure xmlns:common="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/common" xmlns:structure="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:message="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message" xsi:schemaLocation="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message SDMXMessage.xsd">
  <message:Header>
    <message:ID>70c32d97-bbd5-44c7-8bff-50a63abe07eb</message:ID>
    <message:Test>false</message:Test>
    <message:Prepared>2021-08-26T11:37:37</message:Prepared>
    <message:Sender id="CH1">
      <message:Name>CH1</message:Name>  
    </message:Sender>
  </message:Header>
  <message:CodeLists>
    <structure:CodeList id="CL_LEISTUNGSART" version="1.0" agencyID="CH1" isFinal="true">
      <structure:Name xml:lang="de">Leistungsart</structure:Name>
      <structure:Name xml:lang="fr">Type prestation</structure:Name>
      <structure:Name xml:lang="it">Tipo di prestazione</structure:Name>
      <structure:Code value="01">
      </structure:Code>
      <structure:Code value="02">
        <structure:Description xml:lang="de">Reguläre Unterstützung mit Zielvereinbarung</structure:Description>
        <structure:Description xml:lang="fr">Aide financière régulière avec contrat d'insertion</structure:Description>
        <structure:Description xml:lang="it">Assistenza regolare con contratto d’inserimento</structure:Description>
        <structure:Annotations>
        </structure:Annotations>
      </structure:Code>
      <structure:Code value="03">
      </structure:Code>
      <structure:Code value="04">
      </structure:Code>
      <structure:Code value="05">
      </structure:Code>
      <structure:Code value="10">
      </structure:Code>
      <structure:Code value="21">
      </structure:Code>
      <structure:Code value="22">
      </structure:Code>
      <structure:Code value="23">
      </structure:Code>
      <structure:Code value="25">
      </structure:Code>
      <structure:Code value="26">
      </structure:Code>
      <structure:Code value="32">
      </structure:Code>
      <structure:Code value="33">
      </structure:Code>
      <structure:Code value="34">
      </structure:Code>
      <structure:Code value="35">
      </structure:Code>
      <structure:Code value="36">
      </structure:Code>
      <structure:Code value="37">
      </structure:Code>
      <structure:Code value="40">
      </structure:Code>
      <structure:Code value="50">
      </structure:Code>
      <structure:Annotations>
      </structure:Annotations>
    </structure:CodeList>
    <structure:CodeList id="CL_LEISTUNGSART" version="2.0" agencyID="CH1">
    </structure:CodeList>
  </message:CodeLists>
</message:Structure>

请求是:从结构中选择version最高且isFinal为真的一个CodeList,然后读取Code元素(及其子元素)。

我可以从结构命名空间中选择 CodeList 元素:

document.css("structure|CodeList")

但是当我尝试评估属性 versionisFinal 时我迷路了。

您的帮助将不胜感激!

【问题讨论】:

  • 使用 xpath 而不是 css 选择器可能会更好,但是您的 xml 格式不正确,因此很难分辨。尝试使用格式正确的 xml 编辑问题。
  • 你的xml有两个&lt;structure:CodeList&gt;元素;一个具有version 属性的最高属性值(即“2.0”)但没有isFinal 属性;另一个确实具有值为“true”的属性,但version 属性值较低。所以没有什么符合你的条件。您的意思是从具有isFinal 属性的那些中搜索具有最高version 属性值的&lt;structure:CodeList&gt;
  • 另外,您的 xml 格式仍然不正确。先由something like this运行。
  • 感谢您对我的问题的帮助!复制粘贴已截断消息,现在已更正并通过验证。是的,我正在寻找具有 isFinal = true 的最高版本的 CodeList。如果更容易解决,我将切换到 xPath :-)

标签: xml-parsing nokogiri


【解决方案1】:

由于您将在下面看到的原因,这并不是真正的答案,但评论太长了,可能在某种程度上有所帮助。

就纯xpath表达式而言,获取(例如)structure:CodeList节点的structure:Name子节点的法语翻译(满足你的两个要求),如下表达式

//structure:CodeList[@version=max(//*[@isFinal="true"]/number(@version))]/structure:Name[@xml:lang="fr"]/text()

会输出

Type prestation

对于其他语言也类似,例如structure:Description。由于 xml 使用命名空间,因此对于 nokogiri,您必须使用类似

doc.xpath('//structure:CodeList[@version=max(//*[@isFinal="true"]/number(@version))]/structure:Name[@xml:lang="fr"]/text()',
                'structure' => "http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure")

问题在于表达式中使用了max() 函数。我现在无法自己测试,但max() 是一个 xpath 2.0 功能,我的理解是只支持 xpath 1.0。

为什么要解决对更高版本 xpath 的支持问题的一个原因是take a look here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    相关资源
    最近更新 更多