使用 elementree,lxml - 唯一的 (.//) 通配符适用于 findall - 不能使用相对路径?
Using elementree, lxml - the only (.//) wildcard works for findall - cannot use relative paths?
我有一个高度嵌套的长 xml 文件,我需要对其进行解析并进入 pandas DataFrame。
这是我的 XML:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE PPP
SYSTEM 'PPP.DTD'>
<book chg="R" model="AB" >
<chapter chapnbr="09" chg="U" key="EN49" >
<effect effrg="Afcd"/>
<title>HOW TO WIN</title>
<section chapnbr="09" chg="U" key="Edff" revdate="20100701" sectnbr="102">
<title>What a start</title>
<subject chapnbr="09" chg="U" key="Edff" revdate="20100701" sectnbr="102" subjnbr="00">
<title>1.A</title>
<pgblk chapnbr="09" chg="U" confnbr="00" key="Edff00" pgblknbr="00" revdate="20200701" sectnbr="102" subjnbr="00">
<effect effrg="12"/>
<title>1.A.i) Plan Ahead for the worst</title>
<prclist1>
<prcitem1 adns-numbering="8" adns-title="learning my way with help of good people" >
<effect effrg="Edff"/>
<prcitem asFragment="true">
<title>1.A.i) Plan Ahead for the worst</title>
<para>It was a cold January night, and I had too much whisky.
<refblock>
09-102-00
<refint rrr="22,445,555,555,555" refid="Edff0898">
<effect effrg="Edff0899"/>
0910200</refint>
</refblock>. </para>
<para>In more usual circumstances, I possesed the self-control. Not this time
<refblock>
09-102-00-1111
<refint rrr="sdf,2323,2323" refid="Edff123">
<effect effrg="Edff12434"/>
09-102-00</refint>
</refblock>. </para>
</prcitem>
</prcitem1>
</prclist1>
</pgblk>
</subject>
</section>
</chapter>
</book>
由于我不知道的原因,我无法使用相对 XPath 进行提取。只有 findall('.//')
有效,但当然会输出完整的文件。
在高层次上,我可以解析 xml
from lxml import etree
tree = etree.parse('file.xml')
root = tree.getroot()
我还能够获取每个元素的绝对路径:
for e in root.iter():
print(tree.getpath(e))
给出(下面是一个示例,我的实际 xml 嵌套更多,输出 x3 倍以下路径):
/book
/book/chapter
/book/chapter/effect
/book/chapter/title
/book/chapter/section
/book/chapter/section/title
/book/chapter/section/subject
然后我需要从 xml
的特定区域提取标签和文本
但是,如果尝试使用绝对路径或相对路径,字典输出 d
仍为空。
d={}
for item in root.findall('./section/title'):
d[item.tag] = item.text
同样
findall('.//section/title')
再次为
清空字典
findall('/book/chapter/section/title')
唯一有效的 xpath 是:
findall('.//')
findall()
不接受绝对路径名。您需要相对路径名。
'.//section/title'
确实有效,但它是 returns title
标签。因此,无论有多少匹配项,您最终都会在字典中得到一个名为 title
的键,为什么可能不是您想要的。
如果你想使用标题作为章节的索引,你可以这样做:
d = dict((item.text, item.getparent()) for item in root.findall('.//section/title'))
根据您的示例 XML,这会创建一个包含键 What a start
和章节元素作为值的字典。
如果你想使用 XPath 表达式的全部功能,我建议使用 XPathEvaluator
:
from lxml import etree
tree = etree.parse('file.xml')
xev = etree.XPathEvaluator(tree)
d = dict((item.text, item.getparent()) for item in xev('/book/chapter/section/title'))
for k, v in d.items():
print(f"{k} -> {v.tag}")
输出:
What a start -> section
我有一个高度嵌套的长 xml 文件,我需要对其进行解析并进入 pandas DataFrame。
这是我的 XML:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE PPP
SYSTEM 'PPP.DTD'>
<book chg="R" model="AB" >
<chapter chapnbr="09" chg="U" key="EN49" >
<effect effrg="Afcd"/>
<title>HOW TO WIN</title>
<section chapnbr="09" chg="U" key="Edff" revdate="20100701" sectnbr="102">
<title>What a start</title>
<subject chapnbr="09" chg="U" key="Edff" revdate="20100701" sectnbr="102" subjnbr="00">
<title>1.A</title>
<pgblk chapnbr="09" chg="U" confnbr="00" key="Edff00" pgblknbr="00" revdate="20200701" sectnbr="102" subjnbr="00">
<effect effrg="12"/>
<title>1.A.i) Plan Ahead for the worst</title>
<prclist1>
<prcitem1 adns-numbering="8" adns-title="learning my way with help of good people" >
<effect effrg="Edff"/>
<prcitem asFragment="true">
<title>1.A.i) Plan Ahead for the worst</title>
<para>It was a cold January night, and I had too much whisky.
<refblock>
09-102-00
<refint rrr="22,445,555,555,555" refid="Edff0898">
<effect effrg="Edff0899"/>
0910200</refint>
</refblock>. </para>
<para>In more usual circumstances, I possesed the self-control. Not this time
<refblock>
09-102-00-1111
<refint rrr="sdf,2323,2323" refid="Edff123">
<effect effrg="Edff12434"/>
09-102-00</refint>
</refblock>. </para>
</prcitem>
</prcitem1>
</prclist1>
</pgblk>
</subject>
</section>
</chapter>
</book>
由于我不知道的原因,我无法使用相对 XPath 进行提取。只有 findall('.//')
有效,但当然会输出完整的文件。
在高层次上,我可以解析 xml
from lxml import etree
tree = etree.parse('file.xml')
root = tree.getroot()
我还能够获取每个元素的绝对路径:
for e in root.iter():
print(tree.getpath(e))
给出(下面是一个示例,我的实际 xml 嵌套更多,输出 x3 倍以下路径):
/book
/book/chapter
/book/chapter/effect
/book/chapter/title
/book/chapter/section
/book/chapter/section/title
/book/chapter/section/subject
然后我需要从 xml
的特定区域提取标签和文本但是,如果尝试使用绝对路径或相对路径,字典输出 d
仍为空。
d={}
for item in root.findall('./section/title'):
d[item.tag] = item.text
同样
findall('.//section/title')
再次为
清空字典findall('/book/chapter/section/title')
唯一有效的 xpath 是:
findall('.//')
findall()
不接受绝对路径名。您需要相对路径名。
'.//section/title'
确实有效,但它是 returns title
标签。因此,无论有多少匹配项,您最终都会在字典中得到一个名为 title
的键,为什么可能不是您想要的。
如果你想使用标题作为章节的索引,你可以这样做:
d = dict((item.text, item.getparent()) for item in root.findall('.//section/title'))
根据您的示例 XML,这会创建一个包含键 What a start
和章节元素作为值的字典。
如果你想使用 XPath 表达式的全部功能,我建议使用 XPathEvaluator
:
from lxml import etree
tree = etree.parse('file.xml')
xev = etree.XPathEvaluator(tree)
d = dict((item.text, item.getparent()) for item in xev('/book/chapter/section/title'))
for k, v in d.items():
print(f"{k} -> {v.tag}")
输出:
What a start -> section