Nokogiri:NoMethodError(nil:NilClass 的未定义方法 `inner_html')

Nokogiri : NoMethodError (undefined method `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 的文本。去掉header信息到空行再试

我认为它会帮助您阅读 XML spec 或阅读一些有关创建 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> 不一定是 "root" 节点的名称,它只是最外层的标签:

doc = Nokogiri::XML(<<EOT)
<foo>
  <node />
</foo>
EOT

doc.errors # => []

并且仍然会导致文档的有效 DOM/internal 表示:

puts doc.to_html 

# >> <foo>
# >>   <node></node>
# >> </foo>

您的 XML 示例正在使用名称空间,这使事情变得有些复杂。 Nokogiri documentation 讨论了如何处理它们,因此您需要了解解析 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"