Ruby - Nokogiri - нужно поместить node.value в массив - PullRequest
1 голос
/ 12 января 2011

То, что я пытаюсь сделать, это прочитать значение для всех узлов в этом XML и поместить их в массив. Это должно быть просто, но по какой-то причине это сводит меня с ума.

1002 * * 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 ]

4 голосов
/ 13 января 2011

Вот как я бы сделал то, о чем вы спрашиваете:

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 узлов, вам нужно немного подправить код, основываясь на том, как вы хотите обрабатывать вещи, но это не сложно.

3 голосов
/ 12 января 2011

Ваша проблема в том, что этот код ...

@@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>, заполненный значениями в этом элементе.

...