如何将此XML解析为哈希

时间:2013-03-11 17:26:58

标签: ruby-on-rails ruby

我正在尝试将此xml解析为哈希。我正在使用Hash.from_xml,但是当元素具有值而其他元素作为子元素时,它似乎无法处理大小写。它只会带来价值而不会带走任何孩子。

<?xml version="1.0" encoding="UTF-8"?>
<StatusResponse>
    <AccountID>123</AccountID>
    <ErrorMsg />
    <Test>Y</Test>
    <StatusList>
        <PICNumber>
            9477707123456123456781
            <Status>Youritemwasdeliveredat10:09AMon08/06/2007inPALOALTOCA94301.</Status>
            <StatusBreakdown>
                <Status_1>ArrivalatPostOfficeJune02201110:11amNORTHHOLLYWOODCA91605</Status_1>
                <Status_2>ForwardExpiredJune0220116:59amNORTHHOLLYWOODCA</Status_2>
                <Status_3>ProcessedthroughSortFacilityJune0120114:53pmBELLGARDENSCA90201</Status_3>
                <Status_4>ElectronicShippingInfoReceivedMay312011</Status_4>
                <Status_5>ShipmentAcceptedMay3120114:25pmPALOALTOCA94303</Status_5>
            </StatusBreakdown>
            <StatusCode>D</StatusCode>
       </PICNumber>
    </StatusList>
</StatusResponse>

值9477707123456123456781将正确解析为PicNumber键,但会跳过其下方的所有内容。

2 个答案:

答案 0 :(得分:2)

首先走路,然后跑步。获取所需的值,然后构建哈希:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<?xml version="1.0" encoding="UTF-8"?>
<StatusResponse>
    <AccountID>123</AccountID>
    <ErrorMsg />
    <Test>Y</Test>
    <StatusList>
        <PICNumber>
            9477707123456123456781
            <Status>Youritemwasdeliveredat10:09AMon08/06/2007inPALOALTOCA94301.</Status>
            <StatusBreakdown>
                <Status_1>ArrivalatPostOfficeJune02201110:11amNORTHHOLLYWOODCA91605</Status_1>
                <Status_2>ForwardExpiredJune0220116:59amNORTHHOLLYWOODCA</Status_2>
                <Status_3>ProcessedthroughSortFacilityJune0120114:53pmBELLGARDENSCA90201</Status_3>
                <Status_4>ElectronicShippingInfoReceivedMay312011</Status_4>
                <Status_5>ShipmentAcceptedMay3120114:25pmPALOALTOCA94303</Status_5>
            </StatusBreakdown>
            <StatusCode>D</StatusCode>
      </PICNumber>
    </StatusList>
</StatusResponse>
EOT

account_id = doc.at('AccountID').text

pic = doc.at('StatusList PICNumber')
pic_number = pic.child.text.strip
status_msg = pic.at('Status').text

status_breakdown_statuses = pic.search('StatusBreakdown *').map { |n|
  n.text
}

status_code = pic.at('StatusCode').text

hash = {
  :account_id  => account_id,
  :pic_num     => pic_number,
  :status_msg  => status_msg,
  :statuses    => status_breakdown_statuses,
  :status_code => status_code
}

在IRB中看起来像:

{
     :account_id => "123",
        :pic_num => "9477707123456123456781",
       :status_m => "Youritemwasdeliveredat10:09AMon08/06/2007inPALOALTOCA94301.",
       :statuses => [
        [0] "ArrivalatPostOfficeJune02201110:11amNORTHHOLLYWOODCA91605",
        [1] "ForwardExpiredJune0220116:59amNORTHHOLLYWOODCA",
        [2] "ProcessedthroughSortFacilityJune0120114:53pmBELLGARDENSCA90201",
        [3] "ElectronicShippingInfoReceivedMay312011",
        [4] "ShipmentAcceptedMay3120114:25pmPALOALTOCA94303"
    ],
    :status_code => "D"
}

你想要的并不是很清楚,所以这是一些获取XML部分的示例代码。根据收到的XML和我的需求,我可能会采用不同的方式。

答案 1 :(得分:1)

使用nokogiri宝石。读我很简单。