思考以下树型迭代问题的工作方式已经打结了我的大脑,也许有些人可以帮助解决/解决问题。
我有(TEI)个XML文本,并希望按<milestone>
s对其进行分段。为了标记分段,我想使用<milestone>
父元素<div>
的和属性。我认为这意味着我不能使用itertext()
方法,因为它不允许我在处理文本节点时访问那些属性。因此,我的方法是使用iter()
方法,将所有文本内容输入缓冲区,并在遇到里程碑元素时将其刷新到输出段(该段的标签和文本内容的字典)中。当我不在迭代中的里程碑元素上时,我将当前节点的.text
写入缓冲区。
困难的是何时以及如何处理.tail
文本:当我仅测试.tail
的当前节点并将其附加到缓冲区时,它将出现在.text
之前当前节点的子节点(实际上应该在之后),如果我不对其进行测试,我将再也没有机会抓住它,还是我弄错了?
我可以完全使用lxml的iter()
还是必须构建自己的递归迭代函数? (我之前曾尝试通过XPath表达式对文本进行分段,但其性能无法接受(> 24h)。
我为冗长且混乱的xml代码段道歉,但是我无法弄清楚我可以整理或跳过哪些段落来解决这个问题。 (以及其他一些问题(例如this)由于我的XML更加混乱而无法准确应用。
感谢您的帮助。
代码:
from typing import Dict
import lxml
from lxml import etree
def segment(chapter: lxml.etree._Element) -> Dict[str, str]:
segments = {} # this will be returned
t = [] # this is a buffer
chap_label = str(chapter.get("n"))
sect_label = "0"
for element in chapter.iter():
if element.get("unit")=="number":
# milestone: fill and close the previous segment:
label = chap_label + "_" + sect_label
segments[label] = " ".join(t)
# reset buffer
t = []
# if there is text after the milestone,
# add it as first content to the buffer
if element.tail:
t.append(" ".join(str.replace(element.tail, "\n", " ").strip().split()))
# prepare for next labelmaking
sect_label = str(element.get("n"))
else:
if element.text:
t.append(" ".join(str.replace(element.text, "\n", " ").strip().split()))
if element.tail:
t.append(" ".join(str.replace(element.tail, "\n", " ").strip().split()))
# all elements are processed,
# add text remainder/current text buffer content
label = chap_label + "_" + sect_label
segments[label] = " ".join(t)
return segments
nsmap = {"tei": "http://www.tei-c.org/ns/1.0"}
xp_divs = etree.XPath("(//tei:body/tei:div)", namespaces = nsmap)
segmented = {}
divs = xp_divs(document)
segments = (segment(div) for div in divs)
for d in segments:
print(d)
输入文档(我在其中留了很多文字,因此更容易看到短语在输出文档中的结尾位置)
document=etree.fromstring("""
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<text>
<body>
<div n="1">
<p>
... <milestone unit="number" n="9"/>aun que el amor de Dios ha de ser
grandissimo ..., como despues de. S. Tho.
<ref target="#nm-0406">b</ref><note xml:id="nm-0406"><p>1. Sec. quaestio
109. ar. 3.</p></note>, poco ha lo tratamos
<ref target="#nm-0407">c</ref><note xml:id="nm-0407"><p>in addit. ca.
Quoniam. de consec. disti. 1. nu. 10.</p></note>. Anadimos, (virtual)
<milestone unit="number" n="10"/>porque aquella basta, ...
<ref target="#nm-0408">d</ref><note xml:id="nm-0408"><p>in 4. dis. 14.
q. 1. art. 3.</p></note>, que pone exemplo ..., que Gabriel sigue
<ref target="#nm-0409">e</ref><note xml:id="nm-0409"><p>in 4. dis. 14.
q. 1. col. 12. & 13. & in. 3. di. 27. q. 1. co. 15.</p></note>.
<milestone unit="other" rendition="#asterisk"/> Y aun, aquel doctissimo,
... <ref target="#nm-040a">f</ref><note xml:id="nm-040a"><p>In Codice de
poeni. q. 2.</p></note>, y con razon, ..., el martyrio atribuya esto
<ref target="#nm-040b">g</ref><note xml:id="nm-040b"><p>Lib. 2. c. 16.
de natu. & gra.</p></note>, porque mas haze para esto el amor, ...
que lo que se padece <ref target="#nm-040c">h</ref><note xml:id="nm-040c">
<p>Arg. c. 13. 1. ad Corinth.</p></note>. Y puede ser que mas ame, ...,
como lo prueua bien Medina
<ref target="#nm-040d">i</ref><note xml:id="nm-040d"><p>in predi.
q. 2.</p></note>. Por lo qual largamente paresce quan lexos esta esto
dela opinion de Luthero<milestone unit="other" rendition="#asterisk"/>.
De lo dicho se collige la razon, ..., segun Syluestro
<ref target="#nm-040e">k</ref><note xml:id="nm-040e"><p>verb. Contritio.
q. 1.</p></note>. Diximos <milestone unit="number" n="11"/> (auer
pecado,) porque el arrepentimiento ...
</p>
</div>
</body>
</text>
</TEI>""")
结果(出于可读性考虑,将其换行并在此处显示为csv):
1_9,"aun que el amor de Dios ha de ser grandissimo ..., como despues
de. S. Tho. b , poco ha lo tratamos 1. Sec. quaestio 109. ar. 3.
c . Anadimos, (virtual) in addit. ca. Quoniam. de consec. disti.
1. nu. 10."
1_10,"porque aquella basta, ... d , que pone exemplo ..., que Gabriel
sigue in 4. dis. 14. q. 1. art. 3. e . in 4. dis. 14. q. 1. col.
12. & 13. & in. 3. di. 27. q. 1. co. 15. Y aun, aquel doctissimo,
... f, y con razon, ..., el martyrio atribuya esto In Codice de
poeni. q. 2. g , porque mas haze para esto el amor, ... que lo que
se padece Lib. 2. c. 16. de natu. & gra. h . Y puede ser que mas
ame, ..., como lo prueua bien Medina Arg. c. 13. 1. ad Corinth.
i . Por lo qual largamente paresce quan lexos esta esto dela
opinion de Luthero in predi. q. 2. . De lo dicho se collige la
razon, ..., segun Syluestro k . Diximos verb. Contritio. q. 1."
1_11,"(auer pecado,) porque el arrepentimiento ..."
(例如,您可以看到注释nm-0408
的内容应位于“ porque aquella basta,... d”之后,但仅在“ que Gabriel sigue”之后出现。 ..)