有没有一种方法可以让我从 XML 文件中的类似标签中获取我想要的指定数据?
Is there a way that I can just get specified data that I want from similar tags inside an XML file?
我有这个 XML 文件,其中包含大量数据。这是一种非常糟糕的格式,在一个属性中有多个值。
<Person>
<GenericItem html="Name:John<br/>ID: ID-001<br/>Position: Manager<a href="mailto: john@person.com">john@person.com</a><br/>Division: chicken-01">
Employee:
</GenericItem>
<GenericItem string="Hardworking and leader of the chicken division">
Summary
</GenericItem>
<GenericItem link ="person.com/john01">
Profile
</GenericItem>
</Person>
<Person>
<GenericItem html="Name:Anna<br/>ID: ID-002<br/>Position: Fryer<a href="mailto: anna@person.com">anna@person.com</a><br/>Division: chicken-01">
Employee:
</GenericItem>
<GenericItem string="Chicken fryer of the month">
Summary
</GenericItem>
<GenericItem link ="person.com/anna02">
Profile
</GenericItem>
</Person>
<Person>
<GenericItem html="Name:Kent<br/>ID: ID-003<br/>Position: Cleaner<a href="mailto: kent@person.com">kent@person.com</a><br/>Division: chicken-02">
Employee:
</GenericItem>
<GenericItem string="chicken and office cleaner">
Summary
</GenericItem>
<GenericItem link ="person.com/kent03">
Profile
</GenericItem>
</Person>
现在,数据不是全部,因为它会太多。我想要得到的只是“姓名”、“ID”和“职位”。这意味着在 GenericItem 中除了 3 之外不需要并且需要删除并且具有属性“string”和“link”的 GenericItem 是无用的,我想删除它。我尝试使用 Etree del 方法,但我没有删除它们。
import xml.etree.ElementTree as ET
tree = ET.parse('NewestReport.xml')
root = tree.getroot()
for GenericItem in tree.findall('GenericItem'):
del(GenericItem.attrib['string'])
for neighbor in root.iter('GenericItem'):
print(neighbor.attrib)
还有其他方法可以尝试吗?
您需要HTML-解析属性值。
您最好的选择是从内置的 ElementTree 切换到 lxml,因为它包括 XML 和 HTML 解析器,以及适当的 XPath 支持。
我在这里将您的测试输入解析为 XML,并将每个 @html
属性分别解析为 HTML。之后,选择包含 ':'
的文本节点似乎是一个很好的初步近似。当然,您可以以不同的方式剖析 HTML 树。
from lxml import etree as ET
html_parser = ET.HTMLParser()
tree = ET.parse('test.xml')
for person in tree.xpath('./Person'):
print('-' * 40)
for html in person.xpath('./GenericItem/@html')
data = ET.fromstring(html, html_parser)
for text in data.xpath('.//text()[contains(., ":")]'):
print(text.strip())
打印
----------------------------------------
Name:John
ID: ID-001
Position: Manager
Division: chicken-01
----------------------------------------
Name:Anna
ID: ID-002
Position: Fryer
Division: chicken-01
----------------------------------------
Name:Kent
ID: ID-003
Position: Cleaner
Division: chicken-02
我有这个 XML 文件,其中包含大量数据。这是一种非常糟糕的格式,在一个属性中有多个值。
<Person>
<GenericItem html="Name:John<br/>ID: ID-001<br/>Position: Manager<a href="mailto: john@person.com">john@person.com</a><br/>Division: chicken-01">
Employee:
</GenericItem>
<GenericItem string="Hardworking and leader of the chicken division">
Summary
</GenericItem>
<GenericItem link ="person.com/john01">
Profile
</GenericItem>
</Person>
<Person>
<GenericItem html="Name:Anna<br/>ID: ID-002<br/>Position: Fryer<a href="mailto: anna@person.com">anna@person.com</a><br/>Division: chicken-01">
Employee:
</GenericItem>
<GenericItem string="Chicken fryer of the month">
Summary
</GenericItem>
<GenericItem link ="person.com/anna02">
Profile
</GenericItem>
</Person>
<Person>
<GenericItem html="Name:Kent<br/>ID: ID-003<br/>Position: Cleaner<a href="mailto: kent@person.com">kent@person.com</a><br/>Division: chicken-02">
Employee:
</GenericItem>
<GenericItem string="chicken and office cleaner">
Summary
</GenericItem>
<GenericItem link ="person.com/kent03">
Profile
</GenericItem>
</Person>
现在,数据不是全部,因为它会太多。我想要得到的只是“姓名”、“ID”和“职位”。这意味着在 GenericItem 中除了 3 之外不需要并且需要删除并且具有属性“string”和“link”的 GenericItem 是无用的,我想删除它。我尝试使用 Etree del 方法,但我没有删除它们。
import xml.etree.ElementTree as ET
tree = ET.parse('NewestReport.xml')
root = tree.getroot()
for GenericItem in tree.findall('GenericItem'):
del(GenericItem.attrib['string'])
for neighbor in root.iter('GenericItem'):
print(neighbor.attrib)
还有其他方法可以尝试吗?
您需要HTML-解析属性值。
您最好的选择是从内置的 ElementTree 切换到 lxml,因为它包括 XML 和 HTML 解析器,以及适当的 XPath 支持。
我在这里将您的测试输入解析为 XML,并将每个 @html
属性分别解析为 HTML。之后,选择包含 ':'
的文本节点似乎是一个很好的初步近似。当然,您可以以不同的方式剖析 HTML 树。
from lxml import etree as ET
html_parser = ET.HTMLParser()
tree = ET.parse('test.xml')
for person in tree.xpath('./Person'):
print('-' * 40)
for html in person.xpath('./GenericItem/@html')
data = ET.fromstring(html, html_parser)
for text in data.xpath('.//text()[contains(., ":")]'):
print(text.strip())
打印
----------------------------------------
Name:John
ID: ID-001
Position: Manager
Division: chicken-01
----------------------------------------
Name:Anna
ID: ID-002
Position: Fryer
Division: chicken-01
----------------------------------------
Name:Kent
ID: ID-003
Position: Cleaner
Division: chicken-02