web-dev-qa-db-ja.com

Pythonを使用してminidomで要素値を取得する

PythonでEve Online APIのGUIフロントエンドを作成しています。

サーバーからXMLデータを正常にプルしました。

「name」というノードから値を取得しようとしています。

from xml.dom.minidom import parse
dom = parse("C:\\eve.xml")
name = dom.getElementsByTagName('name')
print name

これはノードを見つけるようですが、出力は以下のとおりです。

[<DOM Element: name at 0x11e6d28>]

ノードの値を出力するにはどうすればよいですか?

99
RailsSon

それだけである必要があります

name[0].firstChild.nodeValue
141
eduffy

おそらくあなたが望むテキスト部分ならこのようなものです...

from xml.dom.minidom import parse
dom = parse("C:\\eve.xml")
name = dom.getElementsByTagName('name')

print " ".join(t.nodeValue for t in name[0].childNodes if t.nodeType == t.TEXT_NODE)

ノードのテキスト部分は、それ自体が、要求したノードの子ノードとして配置されたノードと見なされます。したがって、すべての子を調べて、テキストノードであるすべての子ノードを検索する必要があります。ノードには複数のテキストノードを含めることができます。例えば。

<name>
  blabla
  <somestuff>asdf</somestuff>
  znylpx
</name>

「blabla」と「znylpx」の両方が必要です。したがって、 "" .join()です。スペースを改行などで置き換えるか、何もしないこともできます。

56

このようなものを使用できます。

doc = parse('C:\\eve.xml')
my_node_list = doc.getElementsByTagName("name")
my_n_node = my_node_list[0]
my_child = my_n_node.firstChild
my_text = my_child.data 
print my_text
11
samaksh

上記の答えは正しい、すなわち:

name[0].firstChild.nodeValue

しかし、私にとって、他の人と同様に、私の価値はさらに下にありました。

name[0].firstChild.firstChild.nodeValue

これを見つけるために、私は以下を使用しました:

def scandown( elements, indent ):
    for el in elements:
        print("   " * indent + "nodeName: " + str(el.nodeName) )
        print("   " * indent + "nodeValue: " + str(el.nodeValue) )
        print("   " * indent + "childNodes: " + str(el.childNodes) )
        scandown(el.childNodes, indent + 1)

scandown( doc.getElementsByTagName('text'), 0 )

Inkscapeで作成した単純なSVGファイルに対してこれを実行すると、次のことがわかりました。

nodeName: text
nodeValue: None
childNodes: [<DOM Element: tspan at 0x10392c6d0>]
   nodeName: tspan
   nodeValue: None
   childNodes: [<DOM Text node "'MY STRING'">]
      nodeName: #text
      nodeValue: MY STRING
      childNodes: ()
nodeName: text
nodeValue: None
childNodes: [<DOM Element: tspan at 0x10392c800>]
   nodeName: tspan
   nodeValue: None
   childNodes: [<DOM Text node "'MY WORDS'">]
      nodeName: #text
      nodeValue: MY WORDS
      childNodes: ()

Xml.dom.minidomを使用しました。さまざまなフィールドは このページで説明されているMiniDom Pythonです

8
LazyBrush

私はこの質問が今ではかなり古いことを知っていますが、 ElementTree

from xml.etree import ElementTree as ET
import datetime

f = ET.XML(data)

for element in f:
    if element.tag == "currentTime":
        # Handle time data was pulled
        currentTime = datetime.datetime.strptime(element.text, "%Y-%m-%d %H:%M:%S")
    if element.tag == "cachedUntil":
        # Handle time until next allowed update
        cachedUntil = datetime.datetime.strptime(element.text, "%Y-%m-%d %H:%M:%S")
    if element.tag == "result":
        # Process list of skills
        pass

私はそれが超特定ではないことを知っていますが、私はそれを発見したばかりで、これまでのところ、ミニドームよりも頭を動かすのがずっと簡単です(非常に多くのノードが本質的に空白であるため)。

たとえば、予想どおり、タグ名と実際のテキストが一緒にあります。

>>> element[0]
<Element currentTime at 40984d0>
>>> element[0].tag
'currentTime'
>>> element[0].text
'2010-04-12 02:45:45'e
7
LarrikJ

これは、複数ノードのHenrikの回答をわずかに変更したものです(つまり、getElementsByTagNameが複数のインスタンスを返す場合)

images = xml.getElementsByTagName("imageUrl")
for i in images:
    print " ".join(t.nodeValue for t in i.childNodes if t.nodeType == t.TEXT_NODE)
2
khany

私は同様のケースを持っていました、私のために働いたのは:

name.firstChild.childNodes [0] .data

XMLは単純であると想定されており、実際にそうであり、pythonのminidomがなぜそれほど複雑になったのかはわかりません...

2
robertzp

質問は回答されました。私の貢献は、初心者を混乱させる可能性がある1つのことを明確にすることにあります。

提案された正しい回答のいくつかはfirstChild.dataを使用し、他の回答はfirstChild.nodeValueを代わりに使用しました。両者の違いを知りたい場合は、nodeValuedataのエイリアスであるため、同じことを行うことを忘れないでください。

私の声明への参照は、 minidomのソースコード に対するコメントとして見つけることができます:

#nodeValuedataのエイリアスです

0