Nokogiri : NoMethodError (undefined 方法 'inner_html' for nil:NilClass)



我试图用nokogiri解析一个简单的XML数据。这是我的XML:

POST /.... HTTP/1.1
Host: ....
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://...."
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="...." xmlns:xsd="...." xmlns:soap="....">
  <soap:Body>
    <WS_QueryOnSec xmlns="......">
      <type>string</type>
      <ID>string</ID>
    </WS_QueryOnSec>
  </soap:Body>
</soap:Envelope>

,这是我的简单请求:

require "nokogiri"
@doc = Nokogiri::XML(request.body.read)
@something = @doc.at('type').inner_html

但Nokogiri找不到Type或ID节点。当我把数据改成这个时,一切都很好:

  <soap:Body>
      <type>string</type>
      <ID>string</ID>
  </soap:Body>

似乎问题是原始文本上面的数据和节点与xmlns或其他属性!如何解决这个问题?

第一个"XML"不是XML。它是包含XML的文本。将标题信息删除到空白行,然后再试一次。

我认为阅读XML规范或阅读一些关于创建XML的教程会帮助你理解它是如何定义的。XML是严格的规范,不允许有任何偏差。语法非常灵活,但是你必须遵守它的规则。

考虑这些例子:

require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
foo
<root>
  <node />
</root>
EOT
doc.errors # => [#<Nokogiri::XML::SyntaxError: Start tag expected, '<' not found>]

删除根标记之外的文本会导致正确的解析:

require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<root>
  <node />
</root>
EOT
doc.errors # => []

<root>不一定是"根"节点的名称,它只是最外层的标签:

doc = Nokogiri::XML(<<EOT)
<foo>
  <node />
</foo>
EOT
doc.errors # => []

,仍然导致文档的有效DOM/内部表示:

puts doc.to_html 
# >> <foo>
# >>   <node></node>
# >> </foo>

您的XML示例使用了名称空间,这使问题变得有些复杂。Nokogiri文档讨论了如何处理它们,因此您需要理解解析XML的这一部分,因为您将再次遇到它。下面是使用它们的简单方法:

require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:xsi="...." xmlns:xsd="...." xmlns:soap="....">
  <Body>
    <WS_QueryOnSec xmlns="......">
      <type>string</type>
      <ID>string</ID>
    </WS_QueryOnSec>
  </Body>
</Envelope>
EOT
namespaces = doc.collect_namespaces
doc.at('type', namespaces).text # => "string"

相关内容

  • 没有找到相关文章

最新更新