我想从文件(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?
答案 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
。然后,您可以使用上下文容器对元素进行处理。