2015-10-12 75 views
2

我想从文件(1,5gb文件)动态解析XML,它看起来像:lxml的iterparse,具有相同的标签名孩子

<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吗?

+0

,如果你的样品更改名称,它工作呢? –

+0

我还没有试过,但它是外部数据馈送,所以我不负责更改它 – mdargacz

回答

2

如果我在样本上运行etree.iterparse,它会发现'product'标记两次:有一个外部和一个内部<product>。外部标签有子元素,其text为空。所以,你需要跳过这些外部'product'标签只与那些没有子元素,例如工作:

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

如果需要处理顶部product标签的所有内容,可以放下所有的内部product场主循环,然后通过路径处理所有的子元素,例如python's lxml and iterparse method

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) 
+0

这是正确的,但我正在构建产品数据,所以我需要两个(子节点的外部和内部文本 ) 与此同时。 – mdargacz

+0

@mdargacz什么问题?在循环内部或'save_product'功能中,您可以区分内部的''和顶部的''标签,因此可以根据您的需要对它们进行不同的处理。 –

+0

是的,他们可以处理不同,但有严格的相关,如果我有几十个产品,我可以肯定,解析后的内部顶部,包含该产品的网址?即使这是真的,我可以制作元组(顶部,内部),然后save_product()。但我宁愿不以这种拙劣的方式来做到这一点。 – mdargacz

相关问题