从具有自关闭标签的XML中导出文本

huangapple go评论59阅读模式
英文:

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:

&lt;?xml version=&#39;1.0&#39; encoding=&#39;UTF8&#39;?&gt;
&lt;?xml-model href=&quot;http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng&quot; type=&quot;application/xml&quot; schematypens=&quot;http://relaxng.org/ns/structure/1.0&quot;?&gt;
&lt;TEI xmlns=&quot;http://www.tei-c.org/ns/1.0&quot;&gt;
  &lt;text&gt;
    &lt;body&gt;
      &lt;ab&gt;
        &lt;pb n=&quot;page1&quot;/&gt;
          &lt;cb n=&quot;1&quot;/&gt;
            &lt;lb xml:id=&quot;DD1&quot; n=&quot;1&quot;/&gt;my sentence 1
            &lt;lb xml:id=&quot;DD2&quot; n=&quot;2&quot;/&gt;my sentence 2
            &lt;lb xml:id=&quot;DD3&quot; n=&quot;3&quot;/&gt;my sentence 3
          &lt;cb n=&quot;2&quot;/&gt;
            &lt;lb xml:id=&quot;DD1&quot; n=&quot;1&quot;/&gt;my sentence 4
            &lt;lb xml:id=&quot;DD2&quot; n=&quot;2&quot;/&gt;my sentence 5
        &lt;pb n=&quot;page2&quot;/&gt;
          &lt;cb n=&quot;1&quot;/&gt;
            &lt;lb xml:id=&quot;DD1&quot; n=&quot;1&quot;/&gt;my sentence 1
            &lt;lb xml:id=&quot;DD2&quot; n=&quot;2&quot;/&gt;my sentence 2
          &lt;cb n=&quot;2&quot;/&gt;
            &lt;lb xml:id=&quot;DD1&quot; n=&quot;1&quot;/&gt;my sentence 3
            &lt;lb xml:id=&quot;DD1&quot; n=&quot;2&quot;/&gt;my sentence 4
      &lt;/ab&gt;
    &lt;/body&gt;
  &lt;/text&gt;
&lt;/TEI&gt;

I have tried with LXML to access to the informations, by doing:

with open(file,&#39;r&#39;) as my_file:
    
    root = ET.parse(my_file, parser = ET.XMLParser(encoding = &#39;utf-8&#39;))
    list_pages = root.findall(&#39;.//{http://www.tei-c.org/ns/1.0}pb&#39;)
    for page in list_pages:
        liste_text = page.findall(&#39;.//{http://www.tei-c.org/ns/1.0}lb&#39;)
    
    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(&#39;//*[name()=&quot;pb&quot;]&#39;):
    print(p.xpath(&#39;./@n&#39;)[0].strip())
    for lb in p.xpath(&#39;.//following-sibling::*[not(name()=&quot;cb&quot;)]&#39;):
        if lb.xpath(&#39;name()&#39;) == &quot;pb&quot;:
            break
        else:
            print(lb.tail.strip())

The output should be your expected output.

huangapple
  • 本文由 发表于 2023年2月19日 04:07:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75496091.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定