代码之家  ›  专栏  ›  技术社区  ›  Jason Coon

xml.dom.minidom:获取CDATA值

  •  12
  • Jason Coon  · 技术社区  · 17 年前

    我能够在图像标记(见下面的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 回复  |  直到 17 年前
        1
  •  25
  •   bobince    17 年前

    p、 getElementsByTagName('Category')[0]。第一个孩子

    minidom不会变平<![CDATA[节到纯文本,它将它们保留为DOM CDATA节节点。(可以说,至少是可选的。DOM级别3 LS默认为平展它们,这是值得的,但minidom比DOM L3旧得多。)

    您可能需要的是类别的所有子级的文本数据。在DOM Level 3 Core中,您只需调用:

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

    但是minidom还不支持这一点。但是,最新版本确实支持另一种级别3方法,您可以使用该方法以更迂回的方式执行相同的操作:

    p.getElementsByTagName('Category')[0].firstChild.wholeText
    
        2
  •  8
  •   ironfroggy    17 年前

    CDATA是它自己的节点,因此这里的Category元素实际上有三个子元素,一个空白文本节点、CDATA节点和另一个空白节点。你只是看错了,就是这样。我看不到任何更明显的查询CDATA节点的方法,但您可以这样将其拉出:

    [n for n in category.childNodes if n.nodeType==category.CDATA_SECTION_NODE][0]
    
        3
  •  3
  •   BBog Smith    11 年前

    我遇到了类似的问题。我的解决方案与ironfroggy的回答类似,但以更普遍的方式实施:

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

    CDATA_SECTION_NODE )