我正在使用lxml来操作在xml文件中表示的dbschema。它看起来像这样:
<Tables>
<Table name = "table1">
<Columns>
<Column name="COL1">...</Column>
<Column name="COL2">...
<References>
<Reference>TABLENAME</Reference>
</References>
</Column>
</Table>
...
</Tables>
目前我想查看引用,并获取这些引用的表名和列名。以下作品:
refiter = mytree.iter("Reference")
for r in refiter:
nameiter =r.iterancestors("Table")
for n in nameiter:
tablename = .get("name")
我不喜欢这个解决方案,因为我知道我的名字命令只能迭代一个元素 - 它只有一个父“Table”。似乎在python中我只能在循环中使用迭代器。但我发现它有点傻。我知道我只有一个祖先“桌子”。我可以直接以某种方式取消引用迭代器吗?或者是否有另一种方法可以获得更合适的信息?
答案 0 :(得分:0)
您可以使用xpath来获取所需的祖先
x = """<?xml version="1.0" encoding="utf-8"?>
<Tables>
<Table name = "table1">
<Columns>
<Column name="COL1">...</Column>
<Column name="COL2">...
<References>
<Reference>TABLENAME</Reference>
</References>
</Column>
</Columns>
</Table>
<Table name = "table2">
<Columns>
<Column name="COL2">...</Column>
<Column name="COL3">...
<References>
<Reference>TABLENAME</Reference>
</References>
</Column>
</Columns>
</Table>
</Tables>"""
import lxml.etree as et
xml = et.fromstring(x)
refs = xml.iter("Reference")
print([(ref.xpath("./ancestor::Table/@name")[0], ref.xpath("./ancestor::Column/@name")[0]) for ref in refs])
哪会给你:
[('table1', 'COL2'), ('table2', 'COL3')]
或者,如果列始终是祖父母:
[(ref.xpath("./ancestor::Table/@name")[0], ref.xpath("./../../@name")[0]) for ref in refs]
使用你自己的逻辑,你可以在iterancetors上调用next:
refs = xml.iter("Reference")
for r in refs:
print(next(r.iterancestors("Table")).get("name"))
print(next(r.iterancestors("Column")).get("name"))
哪会给你:
table1
COL2
table2
COL3
答案 1 :(得分:0)
由于您只对迭代器的第一个结果感兴趣,因此可以使用next
方法获取第一个元素,并避免不明确/不必要的for
循环。
xml_string = """
<Tables>
<Table name = "table1">
<Columns>
<Column name="COL1">...</Column>
<Column name="COL2">...
<References>
<Reference>TABLENAME</Reference>
</References>
</Column>
</Columns>
</Table>
<Table name = "table2">
<Columns>
<Column name="COL2">...</Column>
<Column name="COL3">...
<References>
<Reference>TABLENAME</Reference>
</References>
</Column>
</Columns>
</Table>
</Tables>"""
import lxml.etree as ETree
root = ETree.fromstring(bytes(xml_string, 'UTF-8'))
refiter = root.iter('Reference')
for r in refiter:
nameiter = r.iterancestors('Table')
name = next(nameiter).get('name')
print(name)
如果要按索引访问结果,可以先从迭代器生成一个列表。
tables = list(r.iterancestors('Table'))
print(tables[0].get('name'))