ruby - Nokogiri 不在 ruby​​ 中解析 XML - xmlns 问题?

标签 ruby xml web-services nokogiri

给定以下 ruby 代码:

require 'nokogiri'

xml = "<?xml version='1.0' encoding='UTF-8'?>
<ProgramList xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns='http://publisher.webservices.affili.net/'>
  <TotalRecords>145</TotalRecords>
  <Programs>
    <ProgramSummary>
      <ProgramID>6540</ProgramID>
      <Title>Matalan</Title>
      <Limitations>A bit of text
      </Limitations>
      <URL>http://www.matalan.co.uk</URL>
      <ScreenshotURL>http://www.matalan.co.uk/</ScreenshotURL>
      <LaunchDate>2009-11-02T00:00:00</LaunchDate>
      <Status>1</Status>
    </ProgramSummary>
    <ProgramSummary>
      <ProgramID>11787</ProgramID>
      <Title>Club 18-30</Title>
      <Limitations/>
      <URL>http://www.club18-30.com/</URL>
      <ScreenshotURL>http://www.club18-30.com</ScreenshotURL>
      <LaunchDate>2013-05-16T00:00:00</LaunchDate>
      <Status>1</Status>
    </ProgramSummary>
  </Programs>
</ProgramList>"

doc = Nokogiri::XML(xml)
p doc.xpath("//Programs")

给出:

=> []

不是预期的。

如果我删除 xmlns='http://publisher.webservices.affili.net/',将进一步调查从最初的 <ProgramList>标签我得到了预期的输出。

确实,如果我改变 xmlns='http://publisher.webservices.affili.net/'xmlns:anything='http://publisher.webservices.affili.net/'我得到了预期的输出。

所以我的问题是这里发生了什么?这是格式错误的 XML 吗?处理它的最佳策略是什么?

虽然在这个例子中它是硬编码的,但 XML 是(将)来自网络服务。

更新

我意识到我可以使用 remove_namespaces!方法,但 Nokogiri 文档确实说它是 "...probably is not a good thing in general"去做这个。我也很想知道它为什么会发生以及“正确”的 XML 应该是什么。

最佳答案

xmlns='http://publisher.webservices.affili.net/' 表示default namespace对于它出现的元素下的所有元素(包括元素本身)。这意味着所有没有显式命名空间的元素都属于这个命名空间。

XPath 查询没有默认的命名空间(至少在 XPath 1.0 中是这样),因此任何出现在一个没有前缀的名称中都指的是没有命名空间的元素。

在您的代码中,您希望在 http://publisher.webservices.affili.net/ 命名空间中找到 Program 元素(因为这是默认命名空间) ,但正在寻找(在您的 XPath 查询中)no 命名空间中的 Program 元素。

显式specify the namespace in the query ,你可以这样做:

doc.xpath("//pub:Programs", "pub" => "http://publisher.webservices.affili.net/")

Nokogiri 使在根元素上声明的 namespace (如本例)更容易一些,使用相同的前缀为您声明它们。它还将使用 xmlns 前缀声明默认 namespace ,因此您还可以:

doc.xpath("//xmlns:Programs")

这会给你相同的结果。

关于ruby - Nokogiri 不在 ruby​​ 中解析 XML - xmlns 问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28822362/

相关文章:

javascript - rails : JS Controller Being Called Twice for Some Reason

ruby-on-rails - Rails - 在辅助方法中使用 gsub 时无效值表达式

android - 设置 ImageView 的权重和参数

java - 在 ArrayList 中缓存 Spring JPA 中的查询结果

java - 我是否需要对 Web 服务请求调度程序 (Java) 进行单元测试?

ruby - 单击 Ruby Mechanize 中 .each 循环内的链接

ruby-on-rails - Ruby - 在函数括号内传递 block

java - 获取单个 xml 节点 - android dev

xml - 标签内的 Unix XML 解析

java - RESTful webservice 和 HttpServlet 的区别