lxml iterparse,具有相同标记名称的子项

时间:2015-10-12 14:28:07

标签: python xml django scrapy lxml

我想从文件(1,5gb文件)中飞行解析xml,如下所示:

<product product_id="x" name="x" sku_number="x">
    <category>
        <primary>x</primary>
        <secondary>y</secondary>
    </category>
    <URL>
        <product>URL__I_WANT_TO_PULLOUT</product>
        <productImage>x</productImage>
    </URL>
    <description>
        <short>x</short>
        <long>x</long>
    </description>
</product>

我正在使用lxml.etree.iterparse,如:

for event, elem in ET.iterparse(f, events=('end',), tag='product'):
    save_product(elem)

我从xml节点获取所有必需的值。我无法取出的唯一节点是URL>product(它只是空的)。我认为它是由相同的标签名称引起的。除了iterparse之外,有没有办法在飞行中解析xml?

2 个答案:

答案 0 :(得分:2)

如果我在您的示例上运行etree.iterparse,则会发现'product'标记两次:有一个外部{1}}和一个内部<product>。外部标记具有子元素,其text为空。因此,您需要跳过这些外部'product'标记才能使用那些没有子元素的标记,例如:

for event, elem in etree.iterparse(f, events=('end',), tag='product'):
    if not len(elem):
        save_product(elem)

如果需要处理顶部product标记的所有元素,则可以删除主循环中的所有内部product字段,然后按路径处理所有子元素,例如{{ 3}}:

def save_product(elem):
    cat_prim = elem.xpath('category/primary')[0].text;
    cat_sec = elem.xpath('category/secondary')[0].text;
    url_prod = elem.xpath('URL/product')[0].text;
    url_img = elem.xpath('URL/productImage')[0].text;
    desc_short = elem.xpath('description/short')[0].text;
    desc_long = elem.xpath('description/long')[0].text;

for event, elem in etree.iterparse(f, events=('end',), tag='product'):
    if len(elem):
        save_product(elem)

答案 1 :(得分:0)

我知道可能已经很晚了,但是对于那里的任何人,我使用以下解决方案:

   file_contents = xml_file.read()
   xml_obj = etree.fromstring(file_contents)
   context = xml_obj.xpath(tag)

我的tag变量是产品路径,例如//parent/product。然后,您可以使用上下文容器对元素进行处理。