Python:从 xml 中的子属性获取父属性
Python: Getting parent attribute from child attribute in xml
我有一个XMLarea.xml
<area>
<controls>
<internal>yes</internal>
</controls>
<schools>
<school id="001"/>
<time>2020-05-18T14:21:00Z</time>
<venture index="5">
<venture>
<basicData type="class">
<wage numberOfDollars="13" Correction="4.61">
<tax>70</tax>
</wage>
</basicData>
</venture>
</venture>
<venture index="9">
<venture>
<basicData type="class">
<wage numberOfDollars="13" Correction="5.61">
<tax>70</tax>
</wage>
</basicData>
</venture>
</venture>
<school id="056"/>
<time>2020-05-18T14:21:00Z</time>
<venture index="5">
<venture>
<basicData type="class">
<wage numberOfDollars="13">
<tax>70</tax>
</wage>
</basicData>
</venture>
</venture>
<venture index="9">
<venture>
<basicData type="class">
<wage numberOfDollars="13">
<tax>70</tax>
</wage>
</basicData>
</venture>
</venture>
</schools>
我想用Python实现的目标:在学校节点中有多个工资节点(叶子)。如果工资节点(休假)(1 个或多个)有一个名为 Correction 的属性,我想要学校节点的属性值。
所以我脚本的结果应该是:001 因为这所学校在工资节点中有属性 Correction(leave)
首先我使用 ETree 进行了尝试
import xml.etree.ElementTree as ET
data_file = 'area.xml'
tree = ET.parse(data_file)
root = tree.getroot()
t1 = "school"
t2 = "wage"
for e1, e2 in zip(root.iter(t1), root.iter(t2)):
if hasattr(e2,'Correction'):
e2.Correction
print (e1.attrib['id'])
但这没有用。现在我正在尝试使用 minidom 实现我的目标
但是我觉得很难。
到目前为止,这是我的代码:
from xml.dom import minidom
doc = minidom.parse("area.xml")
staffs = doc.getElementsByTagName("wage")
for wage in staffs:
sid = wage.getAttribute("Correction")
print("wage:%s" %
(sid))
输出给出工资属性的所有值更正:
wage:4.61
wage:5.61
wage:
wage:
这显然是不正确的。
我可以使用一些帮助让我朝着正确的方向前进
我正在使用 python 3
提前谢谢你
这里有一个不太聪明的方法。
from simplified_scrapy import SimplifiedDoc, req, utils
html = utils.getFileContent("area.xml")
doc = SimplifiedDoc(html)
schools = doc.selects('school') # Get all schools
n = len(schools)
i = 0
while i < n - 1:
school = schools[i]
school1 = schools[i + 1]
h = doc.html[school._end:school1._start] # Get data between two schools
staffs = doc.getElementsByReg(' Correction="', tag='wage', html=h)
if staffs:
print(school.id, staffs.Correction)
i += 1
last = schools[n - 1]
h = doc.html[last._end:]
staffs = doc.getElementsByReg(' Correction="', tag='wage', html=h)
if staffs:
print(last.id, staffs.Correction)
结果:
001 ['4.61', '5.61']
in a school node there are multiple wage nodes
不是真的。 school
元素为空。 venture
兄弟姐妹有 wage
个后代。由于 wage
不是 school
的后代,因此 select 对应的 school
.
有点棘手
如果您可以使用 lxml you could use XPath 到 select 具有 Correction
属性的 wage
元素,然后 select 前面的第一个 school
元素并获取其 id
属性...
from lxml import etree
tree = etree.parse("area.xml")
schools_with_corrected_wages = set()
for corrected_wage in tree.xpath(".//wage[@Correction]"):
schools_with_corrected_wages.add(corrected_wage.xpath("preceding::school[1]/@id")[0])
print(schools_with_corrected_wages)
这会打印:
{'001'}
您还可以使用 lxml 来处理 XML 和 XSLT...
XSLT 1.0 (test.xsl)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="corrected_wage_by_school" match="wage[@Correction]" use="preceding::school[1]/@id"/>
<xsl:template match="/">
<xsl:for-each select="//school[key('corrected_wage_by_school',@id)]">
<xsl:value-of select="concat(@id,'
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Python
from lxml import etree
tree = etree.parse("area.xml")
xslt = etree.parse("test.xsl")
result = tree.xslt(xslt)
print(result)
这会打印...
001
我有一个XMLarea.xml
<area>
<controls>
<internal>yes</internal>
</controls>
<schools>
<school id="001"/>
<time>2020-05-18T14:21:00Z</time>
<venture index="5">
<venture>
<basicData type="class">
<wage numberOfDollars="13" Correction="4.61">
<tax>70</tax>
</wage>
</basicData>
</venture>
</venture>
<venture index="9">
<venture>
<basicData type="class">
<wage numberOfDollars="13" Correction="5.61">
<tax>70</tax>
</wage>
</basicData>
</venture>
</venture>
<school id="056"/>
<time>2020-05-18T14:21:00Z</time>
<venture index="5">
<venture>
<basicData type="class">
<wage numberOfDollars="13">
<tax>70</tax>
</wage>
</basicData>
</venture>
</venture>
<venture index="9">
<venture>
<basicData type="class">
<wage numberOfDollars="13">
<tax>70</tax>
</wage>
</basicData>
</venture>
</venture>
</schools>
我想用Python实现的目标:在学校节点中有多个工资节点(叶子)。如果工资节点(休假)(1 个或多个)有一个名为 Correction 的属性,我想要学校节点的属性值。
所以我脚本的结果应该是:001 因为这所学校在工资节点中有属性 Correction(leave)
首先我使用 ETree 进行了尝试
import xml.etree.ElementTree as ET
data_file = 'area.xml'
tree = ET.parse(data_file)
root = tree.getroot()
t1 = "school"
t2 = "wage"
for e1, e2 in zip(root.iter(t1), root.iter(t2)):
if hasattr(e2,'Correction'):
e2.Correction
print (e1.attrib['id'])
但这没有用。现在我正在尝试使用 minidom 实现我的目标 但是我觉得很难。
到目前为止,这是我的代码:
from xml.dom import minidom
doc = minidom.parse("area.xml")
staffs = doc.getElementsByTagName("wage")
for wage in staffs:
sid = wage.getAttribute("Correction")
print("wage:%s" %
(sid))
输出给出工资属性的所有值更正:
wage:4.61
wage:5.61
wage:
wage:
这显然是不正确的。
我可以使用一些帮助让我朝着正确的方向前进
我正在使用 python 3
提前谢谢你
这里有一个不太聪明的方法。
from simplified_scrapy import SimplifiedDoc, req, utils
html = utils.getFileContent("area.xml")
doc = SimplifiedDoc(html)
schools = doc.selects('school') # Get all schools
n = len(schools)
i = 0
while i < n - 1:
school = schools[i]
school1 = schools[i + 1]
h = doc.html[school._end:school1._start] # Get data between two schools
staffs = doc.getElementsByReg(' Correction="', tag='wage', html=h)
if staffs:
print(school.id, staffs.Correction)
i += 1
last = schools[n - 1]
h = doc.html[last._end:]
staffs = doc.getElementsByReg(' Correction="', tag='wage', html=h)
if staffs:
print(last.id, staffs.Correction)
结果:
001 ['4.61', '5.61']
in a school node there are multiple wage nodes
不是真的。 school
元素为空。 venture
兄弟姐妹有 wage
个后代。由于 wage
不是 school
的后代,因此 select 对应的 school
.
如果您可以使用 lxml you could use XPath 到 select 具有 Correction
属性的 wage
元素,然后 select 前面的第一个 school
元素并获取其 id
属性...
from lxml import etree
tree = etree.parse("area.xml")
schools_with_corrected_wages = set()
for corrected_wage in tree.xpath(".//wage[@Correction]"):
schools_with_corrected_wages.add(corrected_wage.xpath("preceding::school[1]/@id")[0])
print(schools_with_corrected_wages)
这会打印:
{'001'}
您还可以使用 lxml 来处理 XML 和 XSLT...
XSLT 1.0 (test.xsl)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="corrected_wage_by_school" match="wage[@Correction]" use="preceding::school[1]/@id"/>
<xsl:template match="/">
<xsl:for-each select="//school[key('corrected_wage_by_school',@id)]">
<xsl:value-of select="concat(@id,'
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Python
from lxml import etree
tree = etree.parse("area.xml")
xslt = etree.parse("test.xsl")
result = tree.xslt(xslt)
print(result)
这会打印...
001