代码之家  ›  专栏  ›  技术社区  ›  widjajayd

使用nokogiri(带命名空间)从xml文件读取数据

  •  1
  • widjajayd  · 技术社区  · 5 年前

    我想读取xml数据(下面提供的xml数据),并将其放入哈希数组中。下面是我测试过的程序,我可以读取xml节点,但不知道如何获取元素

    require 'nokogiri'
    require 'open-uri'
    
    doc = Nokogiri::XML(File.read("data.xml"))
    status_group = doc.xpath('//source:HotelRooms/*', 'source' => 'http://example.com')
    # this working and I can get the element of the xml below
    

    从上面我可以得到状态组元素, 我的问题是如何读取每个元素数据并将其放入哈希数组中,以便读取数据 我在听他的回答 this SO answer 但还是会出错

    row_hash = status_group.map{ |row|
      {
        RoomTypeName:  row.at('RoomTypeName').text,
        RoomTax:       row.at('RoomTax').text,
      }
    }
    

        <HotelRoomAvailabilityResponse xmlns="http://example.com">
            <Status>
                <StatusCode>01</StatusCode>
                <Description>Successful: AvailableHotelRoom Successful</Description>
            </Status>
            <ResultIndex>1</ResultIndex>
            <HotelRooms>
                <HotelRoom>
                    <RoomIndex>1</RoomIndex>
                    <RoomTypeName>Superior - Double</RoomTypeName>
                    <Inclusion/>
                    <RoomTypeCode>x1</RoomTypeCode>
                    <RatePlanCode>y1</RatePlanCode>
                    <RoomRate IsPackageRate="false" B2CRates="false" AgentMarkUp="0.00" Currency="USD" RoomFare="87.54" RoomTax="18.36" PrefPrice="1412040.00" TotalFare="105.90" PrefCurrency="IDR">
                        <DayRates>
                            <DayRate Date="2018-12-30T00:00:00" BaseFare="29.17950000"/>
                            <DayRate Date="2018-12-31T00:00:00" BaseFare="29.17950000"/>
                            <DayRate Date="2019-01-01T00:00:00" BaseFare="29.17950000"/>
                        </DayRates>
                        <ExtraGuestCharges>0</ExtraGuestCharges>
                        <ChildCharges>0</ChildCharges>
                        <Discount>0</Discount>
                        <OtherCharges>0</OtherCharges>
                        <ServiceTax>0</ServiceTax>
                    </RoomRate>
                    <RoomPromtion/>
                    <Amenities/>
                </HotelRoom>
                <HotelRoom>
                    <RoomIndex>2</RoomIndex>
                    <RoomTypeName>Superior - Double</RoomTypeName>
                    <Inclusion/>
                    <RoomTypeCode>x2</RoomTypeCode>
                    <RatePlanCode>y2</RatePlanCode>
                    <RoomRate IsPackageRate="false" B2CRates="false" AgentMarkUp="0.00" Currency="USD" RoomFare="87.54" RoomTax="18.36" PrefPrice="1412040.00" TotalFare="105.90" PrefCurrency="IDR">
                        <DayRates>
                            <DayRate Date="2018-12-30T00:00:00" BaseFare="29.17950000"/>
                            <DayRate Date="2018-12-31T00:00:00" BaseFare="29.17950000"/>
                            <DayRate Date="2019-01-01T00:00:00" BaseFare="29.17950000"/>
                        </DayRates>
                        <ExtraGuestCharges>0</ExtraGuestCharges>
                        <ChildCharges>0</ChildCharges>
                        <Discount>0</Discount>
                        <OtherCharges>0</OtherCharges>
                        <ServiceTax>0</ServiceTax>
                    </RoomRate>
                    <RoomPromtion/>
                    <Amenities/>
                </HotelRoom>
            </HotelRooms>
        </HotelRoomAvailabilityResponse>
    
    1 回复  |  直到 4 年前
        1
  •  2
  •   Yurii Verbytskyi    5 年前

    改变 row.at('RoomTax').text,

    row.at('RoomRate').attribute('RoomTax').text
    

    require 'nokogiri'
    require 'open-uri'
    
    # doc = Nokogiri::XML(File.read("data.xml"))
    data_xml = <<-EOT
    <HotelRoomAvailabilityResponse xmlns="http://example.com">
        <Status>
            <StatusCode>01</StatusCode>
            <Description>Successful: AvailableHotelRoom Successful</Description>
        </Status>
        <ResultIndex>1</ResultIndex>
        <HotelRooms>
            <HotelRoom>
                <RoomIndex>1</RoomIndex>
                <RoomTypeName>Superior - Double</RoomTypeName>
                <Inclusion/>
                <RoomTypeCode>x1</RoomTypeCode>
                <RatePlanCode>y1</RatePlanCode>
                <RoomRate IsPackageRate="false" B2CRates="false" AgentMarkUp="0.00" Currency="USD" RoomFare="87.54" RoomTax="18.36" PrefPrice="1412040.00" TotalFare="105.90" PrefCurrency="IDR">
                    <DayRates>
                        <DayRate Date="2018-12-30T00:00:00" BaseFare="29.17950000"/>
                        <DayRate Date="2018-12-31T00:00:00" BaseFare="29.17950000"/>
                        <DayRate Date="2019-01-01T00:00:00" BaseFare="29.17950000"/>
                    </DayRates>
                    <ExtraGuestCharges>0</ExtraGuestCharges>
                    <ChildCharges>0</ChildCharges>
                    <Discount>0</Discount>
                    <OtherCharges>0</OtherCharges>
                    <ServiceTax>0</ServiceTax>
                </RoomRate>
                <RoomPromtion/>
                <Amenities/>
            </HotelRoom>
            <HotelRoom>
                <RoomIndex>2</RoomIndex>
                <RoomTypeName>Superior - Double</RoomTypeName>
                <Inclusion/>
                <RoomTypeCode>x2</RoomTypeCode>
                <RatePlanCode>y2</RatePlanCode>
                <RoomRate IsPackageRate="false" B2CRates="false" AgentMarkUp="0.00" Currency="USD" RoomFare="87.54" RoomTax="18.36" PrefPrice="1412040.00" TotalFare="105.90" PrefCurrency="IDR">
                    <DayRates>
                        <DayRate Date="2018-12-30T00:00:00" BaseFare="29.17950000"/>
                        <DayRate Date="2018-12-31T00:00:00" BaseFare="29.17950000"/>
                        <DayRate Date="2019-01-01T00:00:00" BaseFare="29.17950000"/>
                    </DayRates>
                    <ExtraGuestCharges>0</ExtraGuestCharges>
                    <ChildCharges>0</ChildCharges>
                    <Discount>0</Discount>
                    <OtherCharges>0</OtherCharges>
                    <ServiceTax>0</ServiceTax>
                </RoomRate>
                <RoomPromtion/>
                <Amenities/>
            </HotelRoom>
        </HotelRooms>
    </HotelRoomAvailabilityResponse>
    EOT
    doc = Nokogiri::XML(data_xml)
    status_group = doc.xpath('//source:HotelRooms/*', 'source' => 'http://example.com')
    row_hash = status_group.map{ |row|
      {
        RoomTypeName:  row.at('RoomTypeName').text,
        RoomTax:       row.at('RoomRate').attribute('RoomTax').text,
      }
    }
    
    puts row_hash
    
    
    #=>
    #{:RoomTypeName=>"Superior - Double", :RoomTax=>"18.36"}
    #{:RoomTypeName=>"Superior - Double", :RoomTax=>"18.36"}