Анализ на XML файл с невалидни xml:id стойности (започващи с число)

При условие, че имам XML, както следва: Забележете, че атрибутите xml:id са низове, ЗАПОЧВАЩИ С ЦИФРИ

<node1>
    <text xml:id='7865ft6zh67'>
       <div chapter='0'>
          <div id='theNode'>
              <p xml:id="40">
               A House that has:
                   <p xml:id="45">- a window;</p>
                   <p xml:id="46">- a door</p>
                   <p xml:id="46">- a door</p>
               its a beuatiful house
               </p>
          </div>
       </div>
    </text>
</node1>

Бих искал да намеря текстово заглавие и да получа целия текст от първия p таг, който се появява във възела на текстовото заглавие на книгата

Първият подход може да бъде направен с помощта на отговорите тук: lxml xpath израз за избиране на целия текст под даден дъщерен възел, включително неговите деца (мой собствен въпрос)

Но в този нов XML (в сравнение със споменатия въпрос) xml:id започва с число и както е посочено в един от отговорите, възниква следната грешка при използване на кода:

 xml:id : attribute value 7865ft6zh67 is not an NCName, line 3, column 31

Как все още мога да анализирам XML с това XML несъответствие xml:id?

Засега единственото решение, за което мога да се сетя, е предаването на xml към низ и добавянето на буква в началото на всеки от тези xml:id като:

newXML = '...hange><change xml:id="6f58f74883d55b...'
newXML_repared = newXML.replace('xml:id="','xml:id="XXid')
newXML_repared

from lxml import etree
XML_tree = etree.fromstring(newXML_repared,parser=parser)

но когато го правя, получавам:

 ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.

Някакво предложение?

забележка: Забелязах, че самият низ започва с:

<?xml version="1.0" encoding="UTF-8"?>
<teiCorpus subtype="simple"  ...etc

В урока за lxml е възможно да се прочете: Това обаче изисква низовете на unicode да не указват сами конфликтно кодиране и по този начин да лъжат за истинското си кодиране: (https://lxml.de/parsing.html)

Но все още не знам как да реша проблема тогава

Благодаря.


person JFerro    schedule 21.06.2020    source източник
comment
За предпочитане е да не използвате BS, защото целият останал екип използва lxml, никой в ​​екипа не използва BS и идеята е да се придържаме към една библиотека.   -  person JFerro    schedule 22.06.2020
comment
И очевидно BeautifulSoup сам по себе си не поддържа XPath изрази... имаме нужда от xpath, защото xml-ите, с които работим, са изключително сложни и вложени. Но благодаря за отговора   -  person JFerro    schedule 22.06.2020
comment
С bs4 можете да използвате CSS селектори + собствен API на bs4.   -  person Andrej Kesely    schedule 22.06.2020
comment
Откъде идва лошият XML? Това трябва да се поправи от каквото и да е създал.   -  person mzjn    schedule 22.06.2020


Отговори (1)


Една опция се намира във връзката към предоставените от вас документи (https://lxml.de/parsing.html).

По-конкретно опцията за възстановяване, посочена в опции за анализатора.

пример...

from lxml import etree

XML_content = """
<node1>
    <text xml:id='7865ft6zh67' title="book">
       <div chapter='0'>
          <div id='theNode'>
              <p xml:id="40">
               A House that has:
                   <p xml:id="45">- a window;</p>
                   <p xml:id="46">- a door</p>
                   <p xml:id="46">- a door</p>
               its a beuatiful house
               </p>
          </div>
       </div>
    </text>
</node1>
"""

parser = etree.XMLParser(recover=True)

XML_tree = etree.fromstring(XML_content, parser=parser)
text = XML_tree.xpath('normalize-space(//text[@title="book"]/div/div/p)')
# text = XML_tree.xpath('string(//text[@title="book"]/div/div/p)')
print(text)

Забележка: Добавих title="book", така че XPath от другия ми отговор във вашия свързан въпрос все още работи.

person Daniel Haley    schedule 21.06.2020
comment
recover=True на lxml може да бъде полезен за почистване на лош XML, но на читателите трябва да се напомни, че проблеми като започване на идентификатори с цифри нарушават правила за добре оформяне и затова наистина трябва да бъдат фиксирани при източника. В противен случай всеки потребител на XML трябва да страда от тези проблеми, обезсилвайки ползите от използването на стандарти. - person kjhughes; 22.06.2020