我试着阅读Nokogiri文档等,但我遇到了一个障碍。
我得到一个类似于 的XML输出<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getPoliciesResponse xmlns:ns1="http://policy.api.control.r1soft.com/">
<return>
<CDPId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx</CDPId>
<description/>
<diskSafeID>bcb68765-a719-4291-912d-2e6af485ea24</diskSafeID>
<enabled>true</enabled>
<id>cdb65427-d6f4-4a89-9f77-8763e22dc74b</id>
<lastReplicationRunTime>2013-06-12T13:29:40.105-05:00</lastReplicationRunTime>
<name>pstueck-passenger ondemand</name>
<replicationScheduleFrequencyType>ON_DEMAND</replicationScheduleFrequencyType>
<state>OK</state>
</return>
<return>
<CDPId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx</CDPId>
<description/>
<diskSafeID>e8e13555-f577-40d2-99c8-fa8a019d3b55</diskSafeID>
<enabled>true</enabled>
<id>7f55f8d6-92a9-4b14-bff4-631559d92259</id>
<lastReplicationRunTime>2013-06-16T22:00:04.918-05:00</lastReplicationRunTime>
<name>pstueck-mysql daily</name>
<nextReplicationRunTime>2013-06-17T22:00:00-05:00</nextReplicationRunTime>
<replicationScheduleFrequencyType>DAILY</replicationScheduleFrequencyType>
<state>ALERT</state>
<warnings>Policy last completed with alerts</warnings>
</return>
</ns1:getPoliciesResponse>
</soap:Body>
</soap:Envelope>
但是我有一个大#的"返回"部分显示回来。我试图在字符串的末尾使用。search。我只希望它返回整个'返回'部分为给定的'名称'。有人有什么建议吗?
当前代码:client = Savon::Client.new do
http.auth.basic "#{opts['api_username']}", "#{opts['api_password']}"
wsdl.document = "#{opts['api_url']}/Policy?wsdl"
end
getPolicyInformation = client.request :getPolicies
getPolicyInformation = Nokogiri::XML(getPolicyInformation.to_xml)
print getPolicyInformation
如果我搜索指定的<name>
,我想返回<return>
部分中的所有内容。示例:我只想看到与<name>pstueck-passenger ondemand</name>
相关的信息,但是包含<return>
的整个部分
您可以使用XPath识别具有特定值的节点,然后通过执行以下操作来指定感兴趣的祖先元素:
require 'nokogiri'
document = <<-XML
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getPoliciesResponse xmlns:ns1="http://policy.api.control.r1soft.com/">
<return>
<CDPId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx</CDPId>
<description/>
<diskSafeID>bcb68765-a719-4291-912d-2e6af485ea24</diskSafeID>
<enabled>true</enabled>
<id>cdb65427-d6f4-4a89-9f77-8763e22dc74b</id>
<lastReplicationRunTime>2013-06-12T13:29:40.105-05:00</lastReplicationRunTime>
<name>pstueck-passenger ondemand</name>
<replicationScheduleFrequencyType>ON_DEMAND</replicationScheduleFrequencyType>
<state>OK</state>
</return>
<return>
<CDPId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx</CDPId>
<description/>
<diskSafeID>e8e13555-f577-40d2-99c8-fa8a019d3b55</diskSafeID>
<enabled>true</enabled>
<id>7f55f8d6-92a9-4b14-bff4-631559d92259</id>
<lastReplicationRunTime>2013-06-16T22:00:04.918-05:00</lastReplicationRunTime>
<name>pstueck-mysql daily</name>
<nextReplicationRunTime>2013-06-17T22:00:00-05:00</nextReplicationRunTime>
<replicationScheduleFrequencyType>DAILY</replicationScheduleFrequencyType>
<state>ALERT</state>
<warnings>Policy last completed with alerts</warnings>
</return>
</ns1:getPoliciesResponse>
</soap:Body>
</soap:Envelope>
XML
doc = Nokogiri::XML(document)
ns = { 'soap' => 'http://schemas.xmlsoap.org/soap/envelope/', 'ns1' => "http://policy.api.control.r1soft.com/" }
ret = doc.xpath('/soap:Envelope/soap:Body/ns1:getPoliciesResponse/return/name[text()="pstueck-passenger ondemand"]/ancestor::return', ns)
puts ret.count
puts ret.at('replicationScheduleFrequencyType').text
编辑
已更新以反映所讨论的更新的XML主体。现在处理名称空间
使用CSS查找节点:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getPoliciesResponse xmlns:ns1="http://policy.api.control.r1soft.com/">
<return>
<CDPId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx</CDPId>
<description/>
<diskSafeID>e8e13555-f577-40d2-99c8-fa8a019d3b55</diskSafeID>
<enabled>true</enabled>
<id>7f55f8d6-92a9-4b14-bff4-631559d92259</id>
<lastReplicationRunTime>2013-06-16T22:00:04.918-05:00</lastReplicationRunTime>
<name>pstueck-mysql daily</name>
<nextReplicationRunTime>2013-06-17T22:00:00-05:00</nextReplicationRunTime>
<replicationScheduleFrequencyType>DAILY</replicationScheduleFrequencyType>
<state>ALERT</state>
<warnings>Policy last completed with alerts</warnings>
</return>
<return>
<CDPId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx</CDPId>
<description/>
<diskSafeID>bcb68765-a719-4291-912d-2e6af485ea24</diskSafeID>
<enabled>true</enabled>
<id>cdb65427-d6f4-4a89-9f77-8763e22dc74b</id>
<lastReplicationRunTime>2013-06-12T13:29:40.105-05:00</lastReplicationRunTime>
<name>pstueck-passenger ondemand</name>
<replicationScheduleFrequencyType>ON_DEMAND</replicationScheduleFrequencyType>
<state>OK</state>
</return>
</ns1:getPoliciesResponse>
</soap:Body>
</soap:Envelope>
EOT
return_tag = doc.at('return name[text()="pstueck-passenger ondemand"]').parent
puts return_tag.to_xml
输出:<return>
<CDPId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx</CDPId>
<description/>
<diskSafeID>bcb68765-a719-4291-912d-2e6af485ea24</diskSafeID>
<enabled>true</enabled>
<id>cdb65427-d6f4-4a89-9f77-8763e22dc74b</id>
<lastReplicationRunTime>2013-06-12T13:29:40.105-05:00</lastReplicationRunTime>
<name>pstueck-passenger ondemand</name>
<replicationScheduleFrequencyType>ON_DEMAND</replicationScheduleFrequencyType>
<state>OK</state>
</return>
Nokogiri支持XPath和CSS。我发现CSS更容易阅读。
我使用at
方法来查找第一个匹配事件,并且为了显示它是第一个匹配,我交换了两个<return>
块的顺序。at
和search(...).first
是一样的,所以当你在文档中寻找某样东西的第一个实例时,at
是最好的选择。
Nokogiri通常足够聪明,知道XPath和CSS选择器之间的区别,因此我们可以使用通用的at
和search
。如果因为选择器的性别不特定而需要强制CSS或XPath解析,则可以分别使用特定的css
或xpath
或at_css
或at_xpath
。它们都记录在Nokogiri::XML::Node文档中。
parent
是必需的,因为我们需要所选节点的父节点,即<name>
。我只是倒车,倒车了一个街区。这在XPath中更容易实现,我们可以使用..
指向父节点。