Select XML 文件中的某些行 Python
Select some rows from a XML file with Python
我有一个 XML 想要导出一些行,基于属性 1 的内容。
我的文件是这样的:
<Root>
<First_Level_Node>
<Element_Name>
<attribute1>1</attribute1>
<attribute2>2</attribute2>
<attribute3>3</attribute3>
<attribute4>4</attribute4>
<attribute5>5</attribute5>
<attribute6>6</attribute6>
</Element_Name>
<Element_Name>
<attribute1>41</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random value</attribute5>
<attribute6>18th Jun 2014 07:09:18 GMT</attribute6>
</Element_Name>
<Element_Name>
<attribute1>42</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random</attribute5>
<attribute6>23rd Jul 2014 02:47:10 GMT</attribute6>
</Element_Name>
<Element_Name>
<attribute1>43</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random</attribute5>
<attribute6>08th Nov 2014 23:53:31 GMT</attribute6>
</Element_Name>
</First_Level_Node>
</Root>
并且根据属性 1 的值,我想从该元素中获取所有行。
例如,我想要属性 1 = 42 或属性 1 = 43,所以输出将类似于:
<Root>
<First_Level_Node>
<Element_Name>
<attribute1>42</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random</attribute5>
<attribute6>23rd Jul 2014 02:47:10 GMT</attribute6>
</Element_Name>
<Element_Name>
<attribute1>43</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random</attribute5>
<attribute6>08th Nov 2014 23:53:31 GMT</attribute6>
</Element_Name>
</First_Level_Node>
</Root>
我想为此使用 Python。
我尝试使用 ElementTree,但没有成功。这就是我到目前为止所尝试的
with open("output.xml", 'r') as f3:
root = ET.parse(f3)
tree=root.getroot()
with open("list_xxx", 'r') as f2:
for line in f2:
line = line.rstrip()
print (line)
#get all subnet nodes containing certain ManagedElementId
subnet_path = './/*[attribute1="{0}"]'
subnet_path = subnet_path.format(line)
for subnet in tree.findall(subnet_path):
#reconstruct subnet node:
parent = ET.Element(subnet.tag, attrib=subnet.attrib)
#path to find all ManagedElement containing certain ManagedElementId
content_path = ".//*[attribute1='{0}']".format(line)
print (content_path)
#append all ManagedElement found to the new subnet:
for content in subnet.findall(content_path):
parent.append(content)
#print new subnet:
print (ET.tostring(parent))
并且列表 xxx 具有我要查找的属性 1 的值:
41
42
使用 lxml 和 xpath 应该会更简单:
from lxml import etree
dat = """[your xml snippet above]"""
doc = etree.fromstring(dat)
targets = doc.xpath('//Element_Name[not(attribute1="42" or attribute1="43")]')
#the xpath expression above selects all ElementName nodes which do NOT meet your requirements
for target in targets:
target.getparent().remove(target) #once an unnecessary element is selected, you go up to the parent and remove the unnecessary element
print(etree.tostring(doc).decode())
输出就是你想要的输出。
您已经预select编辑了具有指定 attribute1
内容(41 和 42)的 Element_Name
元素。不需要第二次重新 select 它们,这会导致 findall()
.
返回整个 Element_Name
元素
此时您只需要 select 子 attribute1
元素。
因此,如果您更改
content_path = ".//*[attribute1='{0}']".format(line)
到
content_path = "attribute1"
您的程序将打印:
41
attribute1
b'<Element_Name><attribute1>41</attribute1>\n </Element_Name>'
42
attribute1
b'<Element_Name><attribute1>42</attribute1>\n </Element_Name>'
我有一个 XML 想要导出一些行,基于属性 1 的内容。
我的文件是这样的:
<Root>
<First_Level_Node>
<Element_Name>
<attribute1>1</attribute1>
<attribute2>2</attribute2>
<attribute3>3</attribute3>
<attribute4>4</attribute4>
<attribute5>5</attribute5>
<attribute6>6</attribute6>
</Element_Name>
<Element_Name>
<attribute1>41</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random value</attribute5>
<attribute6>18th Jun 2014 07:09:18 GMT</attribute6>
</Element_Name>
<Element_Name>
<attribute1>42</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random</attribute5>
<attribute6>23rd Jul 2014 02:47:10 GMT</attribute6>
</Element_Name>
<Element_Name>
<attribute1>43</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random</attribute5>
<attribute6>08th Nov 2014 23:53:31 GMT</attribute6>
</Element_Name>
</First_Level_Node>
</Root>
并且根据属性 1 的值,我想从该元素中获取所有行。 例如,我想要属性 1 = 42 或属性 1 = 43,所以输出将类似于:
<Root>
<First_Level_Node>
<Element_Name>
<attribute1>42</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random</attribute5>
<attribute6>23rd Jul 2014 02:47:10 GMT</attribute6>
</Element_Name>
<Element_Name>
<attribute1>43</attribute1>
<attribute2></attribute2>
<attribute3>NO</attribute3>
<attribute4>42</attribute4>
<attribute5>random</attribute5>
<attribute6>08th Nov 2014 23:53:31 GMT</attribute6>
</Element_Name>
</First_Level_Node>
</Root>
我想为此使用 Python。
我尝试使用 ElementTree,但没有成功。这就是我到目前为止所尝试的
with open("output.xml", 'r') as f3:
root = ET.parse(f3)
tree=root.getroot()
with open("list_xxx", 'r') as f2:
for line in f2:
line = line.rstrip()
print (line)
#get all subnet nodes containing certain ManagedElementId
subnet_path = './/*[attribute1="{0}"]'
subnet_path = subnet_path.format(line)
for subnet in tree.findall(subnet_path):
#reconstruct subnet node:
parent = ET.Element(subnet.tag, attrib=subnet.attrib)
#path to find all ManagedElement containing certain ManagedElementId
content_path = ".//*[attribute1='{0}']".format(line)
print (content_path)
#append all ManagedElement found to the new subnet:
for content in subnet.findall(content_path):
parent.append(content)
#print new subnet:
print (ET.tostring(parent))
并且列表 xxx 具有我要查找的属性 1 的值:
41
42
使用 lxml 和 xpath 应该会更简单:
from lxml import etree
dat = """[your xml snippet above]"""
doc = etree.fromstring(dat)
targets = doc.xpath('//Element_Name[not(attribute1="42" or attribute1="43")]')
#the xpath expression above selects all ElementName nodes which do NOT meet your requirements
for target in targets:
target.getparent().remove(target) #once an unnecessary element is selected, you go up to the parent and remove the unnecessary element
print(etree.tostring(doc).decode())
输出就是你想要的输出。
您已经预select编辑了具有指定 attribute1
内容(41 和 42)的 Element_Name
元素。不需要第二次重新 select 它们,这会导致 findall()
.
Element_Name
元素
此时您只需要 select 子 attribute1
元素。
因此,如果您更改
content_path = ".//*[attribute1='{0}']".format(line)
到
content_path = "attribute1"
您的程序将打印:
41
attribute1
b'<Element_Name><attribute1>41</attribute1>\n </Element_Name>'
42
attribute1
b'<Element_Name><attribute1>42</attribute1>\n </Element_Name>'