Python ElementTree.Element отсутствует текст?
Итак, я анализирую этот XML-файл умеренного размера (около 27K строк). Не так далеко, я вижу неожиданное поведение от ElementTree.Element, где я получаю Element.text для одной записи, но не для следующей, но она есть в исходном XML, как вы можете видеть:
<!-- language: lang-xml -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:enumeration value="24">
<xs:annotation>
<xs:documentation>UPC12 (item-specific) on cover 2</xs:documentation>
<xs:documentation>AKA item/price; ‘cover 2’ is defined as the inside front cover of a book</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="25">
<xs:annotation>
<xs:documentation>UPC12+5 (item-specific) on cover 2</xs:documentation>
<xs:documentation>AKA item/price; ‘cover 2’ is defined as the inside front cover of a book</xs:documentation>
</xs:annotation>
</xs:enumeration>
Когда я сталкиваюсь с тегом перечисления, я вызываю эту функцию:
import xml.etree.cElementTree as ElementTree
...
def _parse_list_item(xmlns: str, list_id: int, itemElement: ElementTree.Element) -> ListItem:
if isinstance(itemElement, ElementTree.Element):
if itemElement.attrib['value'] is not None:
item_id = itemElement.attrib['value'] # string
if list_id == 6 and (item_id == '25' or item_id=='24'):
print(list_id, item_id) # <== debug break point here
desc = None
notes = ""
for child in itemElement:
if child.tag == (xmlns + 'annotation'):
for grandchild in child:
if grandchild.tag == (xmlns + 'documentation'):
if desc is None:
desc = grandchild.text
else:
if len(notes)>0:
notes += " " # add a space
notes += grandchild.text or ""
if item_id is not None and desc is not None:
return Codex.ListItem({'itemId': item_id, 'listId': list_id, 'description': desc, 'notes': notes})
Если я поставлю точку останова в операторе печати, когда я доберусь до узла перечисления для "24", я смогу посмотреть на текст для узлов внука, и они такие, как показано в XML, то есть "UPC12..." или "AKA item...", но когда я добираюсь до узла перечисления для"25"и смотрю на текст внука, это None.
Когда я удаляю пространство имен xs: путем предварительной фильтрации XML-файла, текст внука проходит нормально.
Возможно, у меня превышен какой-то размер или есть какая-то проблема с синтаксисом?
Извините за менее чем pythonic код, но я хотел иметь возможность проверить все промежуточные значения в pycharm. Это питон 3.6.
Спасибо за любые идеи, которые вы можете иметь!
2 ответа
В for
цикл, это условие никогда не выполняется: if child.tag == (xmlns + 'annotation'):
,
Зачем?
Попробуйте вывести дочерний тег. Если мы предположим, что ваше пространство имен (xmlns)Steve
' затем:
print(child.tag)
будет выводить: {Steve}annotation
не Steveannotation
,
Итак, учитывая этот факт, if child.tag == (xmlns + 'annotation'):
всегда False
,
Вы должны изменить это на: if child.tag == ('{'+xmlns+'}annotation'):
С той же логикой вы обнаружите, что вам также придется изменить это условие:
if grandchild.tag == (xmlns + 'documentation'):
чтобы:
if grandchild.tag == ('{'+xmlns+'}documentation'):
Итак, в конце концов, я решил свою проблему, запустив предварительный процесс для файла XML, чтобы удалить пространство имен xs: из всех тегов открытия / закрытия XML, и затем я смог успешно обработать файл, используя функцию, как определено выше. Не уверен, почему пространства имен вызывают проблемы, но, возможно, в cElementTree есть ошибка для префиксов пространства имен в больших файлах XML. Что касается @mzjn - я ожидаю, что будет трудно создать минимальный пример, поскольку он правильно обрабатывает сотни элементов, прежде чем он завершится сбоем, поэтому мне, по крайней мере, придется предоставить довольно большой файл XML. Тем не менее, спасибо за то, что вы звучите.