Rails nokogiri 解析 XML 文件 [英] Rails nokogiri parse XML file

查看:35
本文介绍了Rails nokogiri 解析 XML 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点困惑:在 web 中找不到使用 nokogiri 解析 xml 的好例子...

I'm a little bit confused: could not find in web good examples of parsing xml with nokogiri...

我的数据示例:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <rows SessionGUID="6448680D1">
        <row>
            <AnalogueCode>0451103079</AnalogueCode>
            <AnalogueCodeAsIs>0451103079</AnalogueCodeAsIs>
            <AnalogueManufacturerName>BOSCH</AnalogueManufacturerName>
            <AnalogueWeight>0.000</AnalogueWeight>
            <CodeAsIs>OC90</CodeAsIs>
            <DeliveryVariantPriceAKiloForClientDescription />
            <DeliveryVariantPriceAKiloForClientPrice>0.00</DeliveryVariantPriceAKiloForClientPrice>
            <DeliveryVariantPriceNote />
            <PriceListItemDescription />
            <PriceListItemNote />
            <IsAvailability>1</IsAvailability>
            <IsCross>1</IsCross>
            <LotBase>1</LotBase>
            <LotType>1</LotType>
            <ManufacturerName>KNECHT/MAHLE</ManufacturerName>
            <OfferName>MSC-STC-58</OfferName>
            <PeriodMin>2</PeriodMin>
            <PeriodMax>4</PeriodMax>
            <PriceListDiscountCode>31087</PriceListDiscountCode>
            <ProductName>Фильтр масляный</ProductName>
            <Quantity>41</Quantity>
            <SupplierID>30</SupplierID>
            <GroupTitle>Замена</GroupTitle>
            <Price>203.35</Price>
        </row>
        <row>
            <AnalogueCode>0451103079</AnalogueCode>
            <AnalogueCodeAsIs>0451103079</AnalogueCodeAsIs>
            <AnalogueManufacturerName>BOSCH</AnalogueManufacturerName>
            <AnalogueWeight>0.000</AnalogueWeight>
            <CodeAsIs>OC90</CodeAsIs>
            <DeliveryVariantPriceAKiloForClientDescription />
            <DeliveryVariantPriceAKiloForClientPrice>0.00</DeliveryVariantPriceAKiloForClientPrice>
            <DeliveryVariantPriceNote />
            <PriceListItemDescription />
            <PriceListItemNote>[0451103079] Bosch,MTGC@0451103079</PriceListItemNote>
            <IsAvailability>1</IsAvailability>
            <IsCross>1</IsCross>
            <LotBase>1</LotBase>
            <LotType>0</LotType>
            <ManufacturerName>KNECHT/MAHLE</ManufacturerName>
            <OfferName>MSC-STC-1303</OfferName>
            <PeriodMin>3</PeriodMin>
            <PeriodMax>5</PeriodMax>
            <PriceListDiscountCode>102134</PriceListDiscountCode>
            <ProductName>Фильтр масляный</ProductName>
            <Quantity>5</Quantity>
            <SupplierID>666</SupplierID>
            <GroupTitle>Замена</GroupTitle>
            <Price>172.99</Price>
        </row>
      </rows>
</root>

和红宝石代码:

...
xml_doc  = Nokogiri::XML(response.body)
parts = xml_doc.xpath('/root/rows/row')

在 xpath 的帮助下,我可以做到这一点吗?还有如何获取这个部分对象(行)?

with the help of xpath i could do this? also how to get this parts object (row)?

推荐答案

您走对了.parts = xml_doc.xpath('/root/rows/row') 返回一个 NodeSet,即 的列表元素.

You're on the right track. parts = xml_doc.xpath('/root/rows/row') gives you back a NodeSet i.e. a list of the <row> elements.

您可以使用 each 或使用诸如 parts[0]parts[1] 之类的行索引来循环访问特定行.然后,您可以在各个行上使用 xpath 获取子节点的值.

You can loop through these using each or use row indexes like parts[0], parts[1] to access specific rows. You can then get the values of child nodes using xpath on the individual rows.

例如您可以为每个部分构建一个 AnalogueCode 列表:

e.g. you could build a list of the AnalogueCode for each part with:

codes = []
parts.each do |row|
  codes << row.xpath('AnalogueCode').text
end

<小时>

查看您正在处理的 XML 的完整示例,有 2 个问题阻止了您的 XPath 匹配:


Looking at the full example of the XML you're processing there are 2 issues preventing your XPath from matching:

  1. 标签实际上不是 XML 的根元素,所以 /root/.. 不匹配

  1. the <root> tag isn't actually the root element of the XML so /root/.. doesn't match

XML 使用命名空间,因此您需要将这些包含在 XPath 中

The XML is using namespaces so you need to include these in your XPaths

所以有几个可能的解决方案:

so there are a couple of possible solutions:

  1. 按照 search)>铁皮人

xml_doc = Nokogiri::XML(response.body) 之后做 xml_doc.remove_namespaces! 然后使用 parts = xml_doc.xpath('//root/rows/row') 其中双斜杠是 XPath 语法,用于在文档中的任何位置定位 root 节点

after xml_doc = Nokogiri::XML(response.body) do xml_doc.remove_namespaces! and then use parts = xml_doc.xpath('//root/rows/row') where the double slash is XPath syntax to locate the root node anywhere in the document

指定命名空间:

例如

xml_doc  = Nokogiri::XML(response.body)
ns = xml_doc.collect_namespaces
parts = xml_doc.xpath('//xmlns:rows/xmlns:row', ns)

codes = []
parts.each do |row|
  codes << xpath('xmlns:AnalogueCode', ns).text
end

我会选择 1. 或 2.:-)

I would go with 1. or 2. :-)

这篇关于Rails nokogiri 解析 XML 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆