Ruby - Nokogiri - 需要将node.value放到数组中

时间:2011-01-12 20:01:12

标签: ruby xml nokogiri

我要做的是读取此XML中所有节点的值并将它们放入数组中。这应该很简单,但由于某种原因,它让我疯了。

XML

<ArrayOfAddress>
<Address>
<AddressId>297424fe-cfff-4ee1-8faa-162971d2645f</AddressId>
<FirstName>George</FirstName>
<LastName>Washington</LastName>
<Address1>123 Main St</Address1>
<Address2>Apt #611</Address2>
<City>New York</City>
<State>NY</State>
<PostalCode>10110</PostalCode>
<CountryCode>US</CountryCode>
<EmailAddress>test@test.com</EmailAddress>
<PhoneNumber>5555551234</PhoneNumber>
<AddressType>CustomerAddress</AddressType>
</Address>
</ArrayOfAddress>

代码

class MassageRepsone
def parse_resp
    @@get_address.url_builder #URL passed through HTTPClient - @@resp is the xml above
      doc = Nokogiri::XML::Reader(@@resp)
      @@values = doc.each do |node|
         node.value
    end
end

    @@get_address.parse_resp
    obj = [@@values] 
    Array(obj)
    p obj
end

上面的代码段返回以下内容:

297424fe-cfff-4ee1-8faa-162971d2645f


George


Washington


123 Main St


Apt #622


New York


NY


10110


US


test.test.com


5555551234


CustomerAddress

我尝试将@@ values添加到一个字符串并应用chomp,但只是将新行打印为nil并在值周围加上引号。不确定下一步是什么,或者我是否需要与Nokogiri进行不同的处理。

2 个答案:

答案 0 :(得分:4)

这就是我要做的事情:

require 'ap'
require 'nokogiri'

xml = <<XML
<ArrayOfAddress>
<Address>
<AddressId>297424fe-cfff-4ee1-8faa-162971d2645f</AddressId>
<FirstName>George</FirstName>
<LastName>Washington</LastName>
<Address1>123 Main St</Address1>
<Address2>Apt #611</Address2>
<City>New York</City>
<State>NY</State>
<PostalCode>10110</PostalCode>
<CountryCode>US</CountryCode>
<EmailAddress>test@test.com</EmailAddress>
<PhoneNumber>5555551234</PhoneNumber>
<AddressType>CustomerAddress</AddressType>
</Address>
</ArrayOfAddress>
XML

doc = Nokogiri::XML(xml)
node_values = doc.search('//Address/*').map do |n|
  n.text
end

ap node_values

哪个输出:

[
    [ 0] "297424fe-cfff-4ee1-8faa-162971d2645f",
    [ 1] "George",
    [ 2] "Washington",
    [ 3] "123 Main St",
    [ 4] "Apt #611",
    [ 5] "New York",
    [ 6] "NY",
    [ 7] "10110",
    [ 8] "US",
    [ 9] "test@test.com",
    [10] "5555551234",
    [11] "CustomerAddress"
]

如果你有多个Address个节点,那么根据你想要处理的方式,你需要稍微调整一下代码,但这并不难。

答案 1 :(得分:3)

你的问题是这段代码......

@@values = doc.each do |node|
  node.value
end

...在每个节点上调用node.value,但不会执行任何结果。 Array#each返回已迭代的数组,这就是您要设置@@values的内容。但是doc.each没有文档中的所有节点。

也许你想要:

# Find all text nodes and extract them individually
@values = doc.xpath('//text()').map{ |node| node.text }

很难确定,因为你最终没有解释数组应该是什么样子。也许你想要:

@addresses = doc.css('Address').map do |address|
  address.xpath( './/text()' ).map{ |node| node.text }
end

...它会为每个<Address>元素提供一个数组的数组,并填充该元素中的值。