0

我正在尝试将此 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 键,但它下面的所有其他内容都将被跳过。

4

2 回答 2

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 和我的需要,我可能会采取不同的做法。

于 2013-03-11T18:58:11.560 回答
1

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

于 2013-03-11T17:32:59.957 回答