2009-02-27 32 views
12

イメージタグ(下記のXMLを参照)では値を取得できますが、カテゴリタグは取得できません。違いは1つはCDATAセクションで、もう1つは文字列であることです。どんな助けもありがとう。xml.dom.minidom: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]) 

答えて

23

p.getElementsByTagName( 'カテゴリー')[0]

を.firstChild minidomが離れて<を平らにしません![CDATA [セクションプレーンテキストには、DOMのCDATASectionノードとしてそれらを残し。 DOM Level 3 LSは、デフォルトでは、値が何であれ、それらを平坦化するのがデフォルトですが、minidomはDOM L3よりはるかに古いです。

したがって、カテゴリのfirstChildは、その間の空白を表すTextノードです<カテゴリ>公開タグとCDATAセクションの開始。それには2つの兄弟があります:CDATASectionノードと後続の空白文字のTextノード。

おそらく、カテゴリのすべての子のテキストデータが必要です。 DOMレベル3コアでは、

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

と呼ばれますが、minidomはそれをまだサポートしていません。最近のバージョンでは、しかし、あなたはもっと遠回しに同じことを行うために使用できる別のレベル3の方法をサポートしていない:

p.getElementsByTagName('Category')[0].firstChild.wholeText 
+0

のですか? –

+0

'getElementsByTagName'は' NodeList'を返し、 '[0]'はリストの最初の要素を取得します。 Python DOMバインディングでは、 '[n]'がDOM '.item(n)'のショートカットになる必要があります。 – bobince

7

は、CDATAは、自ノードであるので、ここカテゴリー要素は、実際には三人の子供、ホワイトスペースを持っていますテキストノード、CDATAノード、および別の空白ノード。あなたは間違ったものを見ているだけです。私は、CDATAノードを照会するために任意のより多くの明白な方法が表示されていないが、あなたはこのようにそれを引き出すことができます。

[n for n in category.childNodes if n.nodeType==category.CDATA_SECTION_NODE][0] 
3

私は同様の問題に遭遇しました。私のソリューションは、ironfroggyが答えたものに類似していたが、より一般的な方法で実装:

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

CDATAのノードタイプはゼロである何4(CDATA_SECTION_NODE

+1

あなたは私のプロジェクトを見知らぬ人に保存しました! –