gpt4 book ai didi

python - 如何从 lxml 正确使用 xmlfile api

转载 作者:行者123 更新时间:2023-12-01 10:51:38 29 4
gpt4 key购买 nike

我有一个大的(超过 5 个演出)XML 文件,我需要对其进行解析、执行一些操作并编写一个新的 XML 文件。

虚拟.xml

<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.namespace.com" catalog-id="test-catalog">
<header>
<name>Product Catalog</name>
</header>

<product product-id="1234">
<available-flag>false</available-flag>
<name>product1</name>
</product>
<product product-id="5678">
<available-flag>false</available-flag>
<name>product1</name>
</product>
<product product-id="9999">
<available-flag>false</available-flag>
<name>product1</name>
</product>
</catalog>

如您所见,上面的 XML 有 3 个 product标签,我需要根据预定义的 ID 列表过滤一些产品 ID。

我正在使用 lxml iterparse迭代地解析 XML 并想使用 xmlfile以增量方式创建新 XML 以保持低内存占用的 API。因此,我的动机是过滤掉不符合条件的产品标签,并按原样复制其余的 XML 标签。

from lxml import etree
f = './dummy.xml'

f1 = './test.xml'
context = etree.iterparse(f, events=('start',))
productsToExport = ['1234']


with etree.xmlfile(f1, encoding='utf-8') as xf:
xf.write_declaration()
with xf.element('catalog xmlns="http://www.namespace.com" catalog-id="test-catalog"'):
for event, element in context:
tagName = etree.QName(element.tag).localname
if (tagName == 'product'):
pid = element.get('product-id')
if (pid in productsToExport):
xf.write(element)
elif (tagName == 'header'):
xf.write(element) # copy existing header tag as it is

上面的代码工作正常并生成如下的 XML

<?xml version='1.0' encoding='utf-8'?>
<catalog xmlns="http://www.namespace.com" catalog-id="test-catalog">
<header xmlns="http://www.namespace.com">
<name>Product Catalog</name>
</header>

<product xmlns="http://www.namespace.com" product-id="1234">
<available-flag>false</available-flag>
<name>product1</name>
</product>
</catalog xmlns="http://www.namespace.com" catalog-id="test-catalog">

如果您观察上面的 XML,它几乎没有问题:

  • 关闭 <catalog>标签有 xmlns & catalog-id出现在里面
  • 所有标签如 header, productxmlns其中存在的属性

我检查了xmlfile api documentation但找不到解决上述问题的方法。

编辑:

我设法通过使用以下方法解决了第一个问题

attribs = {'xmlns' : 'http://www.namespace.com', 'catalog-id' : 'test-catalog'}
with xf.element('catalog', attribs):
# previous logic

因此,现在只剩下从每个元素中删除 namespace 了。

最佳答案

考虑使用 lxml.etree 方法而不是 xmlfile API 简单地重建 XML 树,仍然在 iterparse 的上下文中:

from lxml import etree

f = './dummy.xml'
f1 = './test.xml'
productsToExport = ['1234']

# ROOT ELEMENT WITH DEFUALT NAMESPACE
my_nmsp = {None: 'http://www.namespace.com'}

# INITIALIZE ITERATOR
context = etree.iterparse(f, events=('start',))

for event, element in context:
tagName = etree.QName(element.tag).localname

for prod in productsToExport:
root = etree.Element('catalog', nsmap=my_nmsp)
root.text = '\n\t'
root.attrib['catalog-id'] = "test-catalog"

# PRODUCT ELEMENT
if tagName == 'product':
pid = element.get('product-id')

if pid == prod:
root.append(element)

# HEADER ELEMENT
elif (tagName == 'header'):
root.append(element)

# OUTPUT TREE TO FILE
with open(f1, 'wb') as f:
f.write(etree.tostring(root, pretty_print=True))

输出

<catalog xmlns="http://www.namespace.com" catalog-id="test-catalog">
<header>
<name>Product Catalog</name>
</header>

<product product-id="1234">
<available-flag>false</available-flag>
<name>product1</name>
</product>
</catalog>

关于python - 如何从 lxml 正确使用 xmlfile api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52279722/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com