问题
Here is an XML document:
<Request>
<Field1>value1</Field1>
<Field2>value2</Field2>
<Section1>
<Field attribute1="attrval1">value11</Field>
<Field attribute1="attrval2">value12</Field>
<Field attribute1="attrval3">value13</Field>
<Field attribute1="attrval4">value14</Field>
</Section1>
<Section2>
<Fld1>value21</Fld1>
<Fld2>value22</Fld2>
<Fld3>value23</Fld3>
</Section2>
</Request>
which is parsed by following Ruby code:
xml = Nokogiri::XML(request.raw_post)
req = xml.xpath('/Request')
hash = {
field1: req.xpath('Field1').text,
field2: req.xpath('Field2').text,
section1: req.xpath('Section1/Field').map {|fld|
{
attribute1: fld.attr('attribute1'),
value: fld.text
}
},
section2: req.xpath('Section2').some_method { |sec2|
{
fld1: sec2.xpath('Fld1').text,
fld2: sec2.xpath('Fld2').text,
fld3: sec2.xpath('Fld3').text
}
}
}
Parsing of Section1 is a real working piece of code.
Parsing of non-repeated values in Section2 is a concept - something I would like to see to not have to declare
sec2 = req.xpath('Section2')
before hash declaration.
I would like to see some inline block.
Any suggestions?
回答1:
Not answer, but as alternative you could try:
ActiveSupport::XmlMini.parse(xml)
{"Request"=>
{"Field1"=>{"__content__"=>"value1"},
"Field2"=>{"__content__"=>"value2"},
"Section1"=>
{"Field"=>
[{"attribute1"=>"attrval1", "__content__"=>"value11"},
{"attribute1"=>"attrval2", "__content__"=>"value12"},
{"attribute1"=>"attrval3", "__content__"=>"value13"},
{"attribute1"=>"attrval4", "__content__"=>"value14"}]},
"Section2"=>
{"Fld1"=>{"__content__"=>"value21"},
"Fld2"=>{"__content__"=>"value22"},
"Fld3"=>{"__content__"=>"value23"}}}}
回答2:
You could use map
here, too:
req.xpath('Section2/*').map { |f| [f.name.downcase.to_sym, f.text] }.to_h
# => {:fld1=>"value21", :fld2=>"value22", :fld3=>"value23"}
来源:https://stackoverflow.com/questions/25905884/ruby-hash-declaration-with-an-inline-block-in-the-middle