我发布了我在底部工作的肥皂回复
我需要从BodyType="HTML"
<t:Body BodyType="HTML">
属性
执行response.body
会将整个内容转换为哈希值,并且没有BodyType="HTML"
的迹象。
执行response.doc.css("t|Body")
会生成错误:Undefined namespace prefix: //t:Body (Nokogiri::XML::XPath::SyntaxError)
,因为我在XML中没有看到该命名空间声明。
执行response.doc.css("Body")
返回空白。
我该怎么做才能检索BodyType
的价值?
由于发布发出安全/私有soap请求的代码没有意义,我发布了一些从平面文件中读取XML的基本代码:
require 'savon'
require 'active_support/core_ext/hash/conversions'
require 'nokogiri'
@doc = Nokogiri::XML(File.open("tmp.xml"))
puts @doc.css("t|Body")
这是XML:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="1" MajorBuildNumber="629" MinorBuildNumber="8" Version="V2016_07_13"/>
</s:Header>
<s:Body>
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="AAMkADE2NjQyMjVlLWNhY2UtNDNiMS04MzgxLWZiNzEyNzA0NDgwNQBGAAAAAACLt5QBAQ/GRYv+vEXkY5vLBwA6ksGFFTICTbjFW6e9FfRGAAAAAAEMAAA6ksGFFTICTbjFW6e9FfRGAAAu8FruAAA=" ChangeKey="CQAAABYAAAA6ksGFFTICTbjFW6e9FfRGAAAu9iR3"/>
<t:ParentFolderId Id="AAMkADE2NjQyMjVlLWNhY2UtNDNiMS04MzgxLWZiNzEyNzA0NDgwNQAuAAAAAACLt5QBAQ/GRYv+vEXkY5vLAQA6ksGFFTICTbjFW6e9FfRGAAAAAAEMAAA=" ChangeKey="AQAAAA=="/>
<t:ItemClass>IPM.Note</t:ItemClass>
<t:Subject>From test</t:Subject>
<t:Sensitivity>Normal</t:Sensitivity>
<t:Body BodyType="HTML">Hello world</t:Body>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
答案 0 :(得分:1)
命名空间真的会让水变得混乱。
默认情况下,Nokogiri会在根节点中查找名称空间声明,因此如果在根节点中定义了ChromeOptions options = new ChromeOptions();
options.addArguments("load-extension=" + ext_folder);
WebDriver driver = new ChromeDriver(options);
driver.get("chrome://extensions-frame/");
driver.findElement(By.xpath("//a[@class='extension-commands-config']")).click();
driver.findElement(By.xpath("//span[@class='command-shortcut-text']")).sendKeys(Keys.CONTROL + "m");
driver.findElement(By.id("extension-commands-dismiss")).click();
driver.findElement(By.tagName("body")).sendKeys(Keys.CONTROL + "m");
,t|Body
将起作用。
但是,因为它不是,你必须使用collect_namespaces
告诉Nokogiri搜索文档并构建它找到的所有文件的哈希值。然后,您可以将该哈希值传递给xmlns:t
,search
,css
或任何搜索方法:
at
如果您阅读了require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<m:GetItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<t:Message>
<t:Body BodyType="HTML">Hello world</t:Body>
</t:Message>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
EOT
ns = doc.collect_namespaces # => {"xmlns:s"=>"http://schemas.xmlsoap.org/soap/envelope/", "xmlns:t"=>"http://schemas.microsoft.com/exchange/services/2006/types", "xmlns:m"=>"http://schemas.microsoft.com/exchange/services/2006/messages"}
doc.at("t|Body", ns)['BodyType'] # => "HTML"
的文档,那么您会发现,返回的密钥可能会覆盖以前找到的声明,这是一个潜在的问题。如果出现这样的问题,您可以通过找到collect_namespaces
节点来解决这个问题,然后找到它的第一个子元素,然后收集命名空间:
s:Body
这将导致ns = doc.at('s|Body').first_element_child.namespaces
# => {"xmlns:m"=>"http://schemas.microsoft.com/exchange/services/2006/messages", "xmlns:t"=>"http://schemas.microsoft.com/exchange/services/2006/types", "xmlns:s"=>"http://schemas.xmlsoap.org/soap/envelope/"}
中只有名称空间的哈希: