我有一个非常大的xml,我需要删除另一个节点中的某些特定节点。 例如我有一个列表,其中包含应该存在于xml中的节点的名称。因此,除了这些节点之外,应删除父节点中的所有其他节点并将其写入新的xml文件。
我只需删除节点,即'实例',其中第一个'数据'元素不等于我列表中的值,我将会提供。其余的xml信息,即“描述”,“符号”标签不应受到干扰。
假设:我已经将应该从外部文件读取的数据解析为python列表变量。
DOM或SAX任何人都对我好。但我相信DOM非常快。 对任何BIF可用或逻辑的任何提示对我来说也没问题。
注意:我是Python的新手。所以请在我的代码中注释是否有任何错误。
我的代码如下:
from xml.etree.ElementTree import ElementTree
tree = ElementTree()
tree.parse('Test.xml')
file = open("File.txt")
list = []
for lines in file:
list.append(lines)
Instance = tree.findall('Instance')
for i in Instance:
while (i != list[i]):
Instance.remove(i)
tree.write('new.xml')
以下是示例xml文件:
<?xml version='1.0' encoding='UTF-8'?>
<Identification>
<Description ID="12">Some text</Description>
</Identification>
<Symbols>
<Name Width="1">abc</Name>
<Name Width="2">def</Name>
</Symbols>
<Instance RowRef="A">
<DataSet>
<Data>12345678</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
</Instance>
<Instance RowRef="B">
<DataSet>
<Data>87654321</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
</Instance>
<Instance RowRef="C">
<DataSet>
<Data>06354237/Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
答案 0 :(得分:2)
你在很多方面感到困惑。
首先,您提供的xml缺少根标记。您的xml文件应该看起来更像这样(其中Root
可以替换为必要的标记):
<?xml version='1.0' encoding='UTF-8'?>
<Root>
<Identification>
<Description ID="12">Some text</Description>
</Identification>
<Symbols>
<Name Width="1">abc</Name>
<Name Width="2">def</Name>
</Symbols>
<Instance RowRef="A">
<DataSet>
<Data>12345678</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
</Instance>
<Instance RowRef="B">
<DataSet>
<Data>87654321</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
</Instance>
<Instance RowRef="C">
<DataSet>
<Data>06354237</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
</Instance>
</Root>
第二,如果您担心速度问题,请考虑使用cElementTree
代替ElementTree
:
>>> import xml.etree.cElementTree as ET # use cElementTree for faster processing
第三次,您需要为ET.parse
方法的结果指定一个名称,否则您将无法在以后引用它:
>>> tree = ET.parse('Test.xml')
第四,现在您需要在找到该树的所有Instance
元素之前找到该树的根目录:
>>> root = tree.getroot() # now get the root
>>> keeper_data = ['06354237', '87654321'] # your list that you will apparently get from a file?
>>> instances = root.findall('Instance')
现在您需要找到Instance
个Data
个值表示应删除Instance
元素的元素:
第五,您需要检查第一个Data
元素的文字是否在您的守门员列表中,第六个,您remove
来自root
(或父母恰好是)的元素,而不是来自instances
的元素:
>>> for instance in instances:
data1 = instance.find('./DataSet/Data')
if data1.text not in keeper_data:
# NOTE WELL: I remove from the root (not the instance) below!
root.remove(instance)
现在写入新的xml文件:
>>> tree.write('New.xml')
您生成的xml文件如下所示:
<Root>
<Identification>
<Description ID="12">Some text</Description>
</Identification>
<Symbols>
<Name Width="1">abc</Name>
<Name Width="2">def</Name>
</Symbols>
<Instance RowRef="B">
<DataSet>
<Data>87654321</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
</Instance>
<Instance RowRef="C">
<DataSet>
<Data>06354237</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
<DataSet>
<Data>abcd</Data>
</DataSet>
</Instance>
</Root>
请注意,省略了具有值为12345678的数据元素且没有其他keeper_data元素的实例。