xml.dom.minidom: получение значений CDATA - PullRequest
12 голосов
/ 28 февраля 2009

Я могу получить значение в теге изображения (см. XML ниже), но не тег категории. Разница в том, что один - это раздел CDATA, а другой - просто строка. Любая помощь будет оценена.

from xml.dom import minidom

xml = """<?xml version="1.0" ?>
<ProductData>
    <ITEM Id="0471195">
        <Category>
            <![CDATA[Homogenizers]]>        
        </Category>
        <Image>
            0471195.jpg
        </Image>
    </ITEM>
    <ITEM Id="0471195">
        <Category>
            <![CDATA[Homogenizers]]>        
        </Category>
        <Image>
            0471196.jpg
        </Image>
    </ITEM>
</ProductData>
"""

bad_xml_item_count = 0
data = {}
xml_data = minidom.parseString(xml).getElementsByTagName('ProductData')
parts = xml_data[0].getElementsByTagName('ITEM')
for p in parts:
    try:
        part_id = p.attributes['Id'].value.strip()
    except(KeyError):
        bad_xml_item_count += 1
        continue
    if not part_id:
        bad_xml_item_count += 1
        continue
    part_image = p.getElementsByTagName('Image')[0].firstChild.nodeValue.strip()
    part_category = p.getElementsByTagName('Category')[0].firstChild.data.strip()
    print '\t'.join([part_id, part_category, part_image])

Ответы [ 3 ]

24 голосов
/ 28 февраля 2009

p.getElementsByTagName ( 'Категория') [0] .firstChild

minidom не сглаживается

Таким образом, firstChild of Category - это текстовый узел, представляющий пробел между открытым тегом и началом раздела CDATA. У него есть два родных элемента: узел CDATASection и другой конечный текстовый узел пробельных символов.

То, что вы, вероятно, хотите, это текстовые данные всех детей категории. В DOM Level 3 Core вы бы просто позвонили:

p.getElementsByTagName('Category')[0].textContent

но minidom пока не поддерживает это. Однако в последних версиях поддерживается другой метод уровня 3, который можно использовать, чтобы сделать то же самое более окольным путем:

p.getElementsByTagName('Category')[0].firstChild.wholeText
7 голосов
/ 28 февраля 2009

CDATA - это собственный узел, поэтому у элементов Category здесь фактически есть три дочерних элемента, текстовый узел пробела, узел CDATA и другой узел пробела. Вы просто смотрите не на тот, вот и все. Я не вижу более очевидного способа запроса узла CDATA, но вы можете извлечь его следующим образом:

[n for n in category.childNodes if n.nodeType==category.CDATA_SECTION_NODE][0]
3 голосов
/ 27 мая 2015

Я столкнулся с подобной проблемой. Мое решение было похоже на то, что ответил ironfroggy, но реализовано в более общем виде:

for node in parentNode.childNodes:
        if node.nodeType == 4:
            cdataContent = node.data.strip()

Тип узла CDATA равен 4 (CDATA_SECTION_NODE)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...