Ruby 使用Nokogiri解析XML,但无法解析名称空间

Ruby 使用Nokogiri解析XML,但无法解析名称空间,ruby,xml,curl,nokogiri,Ruby,Xml,Curl,Nokogiri,我有一条XML消息,我的脚本需要能够解析“AccountStatus”节点元素。如果发布的XML没有名称空间,则我的脚本可以正常工作 当我包含原始名称空间时,当脚本执行Nokogiri::XML(request.body.read)时,将丢失大量XML数据 以下是XML示例: curl -i -H -X POST -d "<?xml version="1.0" encoding="utf-8" ?> <DocuSignEnvelopeInformation xmlns="htt

我有一条XML消息,我的脚本需要能够解析“AccountStatus”节点元素。如果发布的XML没有名称空间,则我的脚本可以正常工作

当我包含原始名称空间时,当脚本执行
Nokogiri::XML(request.body.read)
时,将丢失大量XML数据

以下是XML示例:

curl -i -H -X POST -d "<?xml version="1.0" encoding="utf-8" ?>
<DocuSignEnvelopeInformation xmlns="http://www.w3.org/2001/XMLSchema">
    <EnvelopeStatus>
        <RecipientStatuses>
            <RecipientStatus>
                <Type>Signer</Type>
                <CustomFields />
                <AccountStatus>Active</AccountStatus>
                <RecipientId>ab2bf57b-72b7-48e7-8298-b1c7b56930b9</RecipientId>
            </RecipientStatus>
        </RecipientStatuses>
    </EnvelopeStatus>
</DocuSignEnvelopeInformation>" localhost:4567/shunt?uri=http://requestb.in/1hiag0y1
以下是输出:

hello world
<?xml version="1.0"?>
<DocuSignEnvelopeInformation/>
你好,世界
curl问题: 看起来您遇到的第一个问题是curl命令。注意,curl命令指定了一个
-H
选项,但没有指定头。如果我尝试运行您的curl命令,我会得到一个错误:

curl: (6) Couldn't resolve host 'POST'
看起来引号把你的命令搞乱了。在该curl命令中:

curl -i -X POST -d "<?xml version="1.0" encoding="utf-8" ?> ...
curl -i -X POST -d @xml5.xml http://localhost:4567/shunt
curl将从名为file\u name的文件中读取xml。下面是一个例子:

curl -i -X POST -d @./xml_files/xml5.xml http://localhost:4567/shunt 
nokogiri问题: xml中的每个子标记都是默认名称空间的一部分;因此,每个子标记名称前面都有名称空间名称。但是,您只将
docu:
放在xpath的第一个标记前面:

//docu:DocuSignEnvelopeInformation/EnvelopeStatus/....
                                   ^
                                   |
                         missing namespace name
docu:
必须在每个标记名之前。另外,请注意,您可以在xpath中的每个标记前面使用
xmlns:
,而不是指定
docu
名称空间。而且,只需写以下内容就简单得多:

  xpath = '//xmlns:AccountStatus'
供应商向我发送了一条XML消息

如何做到这一点的细节很重要

下面是一个curl命令,用于执行文件上载:

-F
表示上传文件。在本地,xml位于一个名为xml5.xml的文件中。然后,您的sinatra应用程序可以执行以下操作:

post '/shunt' do
  require 'nokogiri'

  doc = Nokogiri::XML(
    params['xmlfile'][:tempfile].read
  )

  xpath = '//xmlns:AccountStatus'
  target_tag = doc.at_xpath(xpath)
  puts target_tag.text
end
或者,使用此curl命令:

curl -i -X POST -d "<?xml version="1.0" encoding="utf-8" ?> ...
curl -i -X POST -d @xml5.xml http://localhost:4567/shunt
…您的路线如下所示:

 -d @file_name
post '/shunt' do
  require 'nokogiri'

  doc = Nokogiri::XML(
    request.body.read
  )

  xpath = '//xmlns:AccountStatus'
  target_tag = doc.at_xpath(xpath)
  puts target_tag.text
end
内容类型标题:
-d
选项将请求中的内容类型标头设置为:

这将导致curl使用内容类型application/x-www-form-urlencoded将数据传递给服务器

-F
选项将请求中的内容类型标题设置为:

这会导致curl使用内容类型multipart/formdata发布数据


谢谢你。是的,我把XML消息中的双引号弄糟了。使用单引号后,问题得到解决。
post '/shunt' do
  require 'nokogiri'

  doc = Nokogiri::XML(
    request.body.read
  )

  xpath = '//xmlns:AccountStatus'
  target_tag = doc.at_xpath(xpath)
  puts target_tag.text
end