Ruby - Nokogiri - Need to put node.value to an array
What I'm trying to do is read the value for all the nodes in this XML and put them into an array. This should be simple but for some reason it's driving me nuts.
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>
Code
class MassageRepsone
def parse_resp
@@get_address.url_builder #URL passed through HTTPClient - @@resp is the xml above
doc = Nokogiri::XML::Reader(@@resp)
@@values = do开发者_如何学运维c.each do |node|
node.value
end
end
@@get_address.parse_resp
obj = [@@values]
Array(obj)
p obj
end
The code snippet from above returns the following:
297424fe-cfff-4ee1-8faa-162971d2645f
George
Washington
123 Main St
Apt #622
New York
NY
10110
US
test.test.com
5555551234
CustomerAddress
I tried putting @@values to a string and applying chomp but that just prints the newlines as nil and puts quotes around the values. Not sure what the next step is or if I need to approach this differently with Nokogiri.
This is how I'd do what it seems you're asking:
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
Which outputs:
[
[ 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"
]
If you have multiple Address
nodes then you'll need to tweak the code a little bit, based on how you want to process things, but it's not hard.
Your problem is that this code...
@@values = doc.each do |node|
node.value
end
...calls node.value
on each node, but then doesn't do anything with the result. Array#each
returns the array that was iterated, and that's what you are setting @@values
to. But doc.each
doesn't have all the nodes in the document.
Perhaps you want:
# Find all text nodes and extract them individually
@values = doc.xpath('//text()').map{ |node| node.text }
It's hard to be sure because you don't explain what the array ought to look like in the end. Perhaps you want:
@addresses = doc.css('Address').map do |address|
address.xpath( './/text()' ).map{ |node| node.text }
end
...which would give you an array of one array for each <Address>
element, filled with the values in that element.
精彩评论