0

我试过阅读 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

如果我<return>搜索指定的<name>. 示例:我只想查看与 相关的信息<name>pstueck-passenger ondemand</name>,但要查看包含该信息的整个<return>部分。

4

2 回答 2

1

您可以使用 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 正文。现在处理命名空间。

于 2013-06-17T18:46:29.917 回答
1

使用 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>块的顺序。atsearch(...).first您在文档中查找某项的第一个实例时at的方法相同。

Nokogiri 通常足够聪明,可以知道 XPath 和 CSS 选择器之间的区别,因此我们可以使用通用的atsearch. 如果因为选择器不区分性别而需要强制进行 CSS 或 XPath 解析,则可以分别使用特定的cssorxpathat_cssor at_xpath。它们都记录在Nokogiri::XML::Node文档中。

parent是必要的,因为我们想要所选节点的父节点,即<name>. 我只是把它撞倒并倒退了一个街区。这在 XPath 中更容易做到,我们可以使用它..来指向父节点。

于 2013-06-17T23:50:43.843 回答