我有以下xml:
<head>
<body>
<para>
<Run>
<Runprop>
<highlight val="red"/>
<break/>
<text>
Hello there
</text>
</RunProp>
</Run>
<Run>
<break/>
</Run>
<Run>
<text>
See you there
</text>
</Run>
</para> ..
</body>
</head>
我想提取所有带有highlight
“红色”值的文字。请注意,highlight
标记的级别低于文本标记的级别。条件是:
highlight
标记的父项时遇到break标记,请添加空格。 highlight
标记我所做的是:
text="" #initialize an empty string
for p in lxml_tree.findall('para'): #itertate over each paragraph (all paragarpahs have the same tag name para)
for r in p.findall("Run"): #iterate over each run
for a in r.iter(tag="highlight"): #search for highlight tag
for b in a.iterancestors(): #go back to the parents
if b.tag=="break": #if break found
text+=" " # add a space
elif b.tag=="text": # if text found
text+=''.join(b.text) #add text
以上似乎不起作用,因为iterancestors一直到达根节点。我怎么可能迭代父母,Runprop
,break
和text
?我已经为所有文本实现了类似的内容,并且有效。
编辑1 :
上面只是一个有缺陷的逻辑,我宁愿迭代段落中的每个Run
,首先搜索break
,然后查看Runprop
中是否有突出显示,然后在父亲的兄弟中提取文本
答案 0 :(得分:2)
我已经设法解决了一些想法,并从anzel的答案中得到了一个想法。
text=""
for p in lxml_tree.findall('para'): #iterate over paragraphs
text+= " " #add spaces
for r in p.findall("Run"): #iterate over each run in para
for a in r.findall("break"): #search for break tag in it and add space if found
text+= " "
for b in r.findall('.//highlight[@val="red"]/../..//text'): #search for red highlight in that run and return text
text+=''.join(b.text) # append text to main string
答案 1 :(得分:1)
由于您的xml具有<highlight>
,<break />
和<text>
的位置模式,因此您实际上不需要返回父级。
我将使用iter
和getnext
来实现您的需求:
from lxml import etree
html = '''
<head>
<body>
<para>
<Run>
<RunProp>
<highlight val="red" />
<break/>
<text>
Hello there
</text>
</RunProp>
</Run>
<Run>
<break/>
</Run>
<Run>
<text>
See you there
</text>
</Run>
</para> ..
</body>
</head>'''
tree = etree.fromstring(html)
for node in tree.iter():
if node.tag == 'para':
node.text = '..your space here..' + node.text
print node.text
if node.tag == 'highlight':
print node.values()
if node.getnext().tag == 'break':
print node.getnext().tag
if node.getnext().getnext().tag == 'text':
node.getnext().getnext().text = \
'..your space here..' + node.getnext().getnext().text
print node.getnext().getnext().text
elif node.getnext().tag == 'text':
print node.getnext().text
..your space here....your space here..
['red']
break
..your space here....your space here..
Hello there
将更改写入文件:
etree.ElementTree(tree).write('output.xml', pretty_print=True)
cat output.xml
<head>
<body>
<para>..your space here..
<Run>
<RunProp>
<highlight val="red"/>
<break/>
<text>..your space here..
Hello there
</text>
</RunProp>
</Run>
<Run>
<break/>
</Run>
<Run>
<text>
See you there
</text>
</Run>
</para> ..
</body>
</head>