あなたがやろうとしていることは些細なことではありません。'pgBreak'要素とそれに続くすべての兄弟を一致させたいだけでなく、それらを親スコープの外に移動し、兄弟を'p'要素でラップしたいとします。楽しいもの。
次のコードは、それを実現する方法を示しています(免責事項:例のみ、クリーンアップが必要、エッジケースはおそらく処理されません)。コードは意図的にコメントされていないので、理解する必要があります:)
機能をわかりやすく説明するために、入力XMLを少し変更しました。
import lxml.etree
text = """
<root>
<pgBreak pgId="1"/>
<p>
some text to fill out a para
<pgBreak pgId="2"/>
some more text
<quote> A quoted block </quote>
remainder of para
<pgBreak pgId="3"/>
<p>
blurb
</p>
</p>
</root>
"""
root = lxml.etree.fromstring(text)
for pgbreak in root.xpath('//pgBreak'):
inner = pgbreak.getparent()
if inner == root:
continue
outer = inner.getparent()
pgbreak_index = inner.index(pgbreak)
inner_index = outer.index(inner) + 1
siblings = inner[pgbreak_index+1:]
inner.remove(pgbreak)
outer.insert(inner_index,pgbreak)
if siblings[0].tag != 'p':
p = lxml.etree.Element('p')
p.text = pgbreak.tail
pgbreak.tail = None
for node in siblings:
p.append(node)
outer.insert(inner_index+1,p)
else:
for node in siblings:
inner_index += 1
outer.insert(inner_index,node)
出力は次のとおりです。
<root>
<pgBreak pgId="1"/>
<p>
some text to fill out a para
</p>
<pgBreak pgId="2"/>
<p>
some more text
<quote> A quoted block </quote>
remainder of para
</p>
<pgBreak pgId="3"/>
<p>
blurb
</p>
</root>