英文:
Export text from xml with self-closing tag
问题
我有一组XML TEI文件,其中包含文档的转录。我想解析这些XML文件并提取只有文本信息。
我的XML看起来像这样:
<?xml version='1.0' encoding='UTF8'?>
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<text>
<body>
<ab>
<pb n="page1"/>
<cb n="1"/>
<lb xml:id="DD1" n="1"/>my sentence 1
<lb xml:id="DD2" n="2"/>my sentence 2
<lb xml:id="DD3" n="3"/>my sentence 3
<cb n="2"/>
<lb xml:id="DD1" n="1"/>my sentence 4
<lb xml:id="DD2" n="2"/>my sentence 5
<pb n="page2"/>
<cb n="1"/>
<lb xml:id="DD1" n="1"/>my sentence 1
<lb xml:id="DD2" n="2"/>my sentence 2
<cb n="2"/>
<lb xml:id="DD1" n="1"/>my sentence 3
<lb xml:id="DD1" n="2"/>my sentence 4
</ab>
</body>
</text>
</TEI>
我尝试使用LXML来访问这些信息,做了以下操作:
with open(file, 'r') as my_file:
root = ET.parse(my_file, parser=ET.XMLParser(encoding='utf-8'))
list_pages = root.findall('.//{http://www.tei-c.org/ns/1.0}pb')
for page in list_pages:
liste_text = page.findall('.//{http://www.tei-c.org/ns/1.0}lb')
final_text = []
for content in liste_text:
final_text.append(content.text)
我想最后得到类似这样的结果:
page1
my sentence 1
my sentence 2
my sentence 3
my sentence 4
my sentence 5
page2
my sentence 1
my sentence 2
my sentence 3
my sentence 4
如果我成功访问了lb对象,那么与它们相关的文本信息没有被提取。你能帮我提取这些信息吗?谢谢
您可以使用以下代码来提取所需的信息:
import xml.etree.ElementTree as ET
file = "your_xml_file.xml"
tree = ET.parse(file)
root = tree.getroot()
final_text = []
current_page = None
for element in root.iter():
if element.tag.endswith("pb"):
current_page = element.get("n")
if element.tag.endswith("lb"):
text = element.tail
if text:
final_text.append((current_page, text.strip()))
for page, text in final_text:
print(page)
print(text)
这将遍历XML文件,提取页码和相关的文本信息,并将其打印出来。
英文:
I have a set of XML TEI files, containing transcriptions of document. I would like to parse these XML file and extract only text informations.
My XML looks like:
<?xml version='1.0' encoding='UTF8'?>
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<text>
<body>
<ab>
<pb n="page1"/>
<cb n="1"/>
<lb xml:id="DD1" n="1"/>my sentence 1
<lb xml:id="DD2" n="2"/>my sentence 2
<lb xml:id="DD3" n="3"/>my sentence 3
<cb n="2"/>
<lb xml:id="DD1" n="1"/>my sentence 4
<lb xml:id="DD2" n="2"/>my sentence 5
<pb n="page2"/>
<cb n="1"/>
<lb xml:id="DD1" n="1"/>my sentence 1
<lb xml:id="DD2" n="2"/>my sentence 2
<cb n="2"/>
<lb xml:id="DD1" n="1"/>my sentence 3
<lb xml:id="DD1" n="2"/>my sentence 4
</ab>
</body>
</text>
</TEI>
I have tried with LXML to access to the informations, by doing:
with open(file,'r') as my_file:
root = ET.parse(my_file, parser = ET.XMLParser(encoding = 'utf-8'))
list_pages = root.findall('.//{http://www.tei-c.org/ns/1.0}pb')
for page in list_pages:
liste_text = page.findall('.//{http://www.tei-c.org/ns/1.0}lb')
final_text = []
for content in liste_text:
final_text.append(content.text)
I would like to have at the end something like:
page1
my sentence 1
my sentence 2
my sentence 3
my sentence 4
my sentence 5
page2
my sentence 1
my sentence 2
my sentence 3
my sentence 4
If I succeed to access to lb objects, no textual informations are linked to them.
Could you please help me to extract these informations?
Thanks
答案1
得分: 1
请注意,您的XML文件可能存在问题,即具有相同属性值的多个xml:id
属性。良好形式的XML要求该值在XML文档内是唯一的。
假设这个问题已经解决,如果您使用lxml而不是ElementTree,将更容易实现,因为lxml具有更好的XPath支持:
from lxml import etree
root = etree.parse(my_file)
for p in root.xpath('//*[name()="pb"]'):
print(p.xpath('./@n')[0].strip())
for lb in p.xpath('.//following-sibling::*[not(name()="cb")]'):
if lb.xpath('name()') == "pb":
break
else:
print(lb.tail.strip())
输出应该是您期望的结果。
英文:
Note that your xml may have a problem in that you have several xml:id
attributes with identical attribute values. Well formed xml requires the value to be unique within the XML document.
Assuming that's fixed, it would be easier to do if you lxml instead of ElementTree, because of lxml's better xpath support:
from lxml import etree
root = etree.parse(my_file)
for p in root.xpath('//*[name()="pb"]'):
print(p.xpath('./@n')[0].strip())
for lb in p.xpath('.//following-sibling::*[not(name()="cb")]'):
if lb.xpath('name()') == "pb":
break
else:
print(lb.tail.strip())
The output should be your expected output.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论