使用Python使用minidom获取Element值

Rai*_*Son 100 python dom 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
Run Code Online (Sandbox Code Playgroud)

这似乎找到了节点,但输出如下:

[<DOM Element: name at 0x11e6d28>]
Run Code Online (Sandbox Code Playgroud)

我怎么能让它打印节点的值?

edu*_*ffy 144

它应该是

name[0].firstChild.nodeValue
Run Code Online (Sandbox Code Playgroud)

  • 为什么有人会设计一个库,其中<name> Smith </ name>的nodeValue除了"Smith"之外什么都没有?!那个小金块花了我30分钟的时间撕掉我的头发.我现在很秃头.谢谢,minidom. (49认同)
  • 那么名字[0] .firstChild.nodeValue怎么样? (28认同)
  • 这只是因为他们设计它的方式来使用html,以允许这样的元素<nodeA> Some Text <nodeinthemiddle> __ complex__structure __ </ nodeinthemiddle>更多文本</ nodeA>,在这种情况下你认为nodeA的nodeValue应该包含所有文本,包括复杂的结构,或者只包含2个文本节点和中间节点.看起来不是最好的方式,但我明白为什么他们这样做了. (9认同)
  • 请注意,您不依赖于xml-generator中的实现细节.在任何可能有多个子节点的情况下,无法保证第一个子节点是*text节点,也不保证*only*text节点. (7认同)
  • 当我做名字[0] .nodeValue给出"无"时,只是为了测试我传给它名称[0] .nodeName它给了我"名字",这是正确的.有任何想法吗? (4认同)

Hen*_*son 56

如果这是你想要的文字部分,可能就是这样的东西......

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)
Run Code Online (Sandbox Code Playgroud)

节点的文本部分被视为一个节点,它本身被放置为您要求的节点的子节点.因此,您将希望遍历其所有子节点并查找作为文本节点的所有子节点.一个节点可以有几个文本节点; 例如.

<name>
  blabla
  <somestuff>asdf</somestuff>
  znylpx
</name>
Run Code Online (Sandbox Code Playgroud)

你想要'blabla'和'znylpx'; 因此"".join().您可能希望用换行符替换空格,或者可能无需替换.


小智 11

你可以使用这样的东西.它对我有用

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
Run Code Online (Sandbox Code Playgroud)


小智 8

以上答案是正确的,即:

name[0].firstChild.nodeValue
Run Code Online (Sandbox Code Playgroud)

然而对我来说,和其他人一样,我的价值还在树下:

name[0].firstChild.firstChild.nodeValue
Run Code Online (Sandbox Code Playgroud)

为了找到这个,我使用了以下内容:

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 )
Run Code Online (Sandbox Code Playgroud)

为我用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: ()
Run Code Online (Sandbox Code Playgroud)

我使用了xml.dom.minidom,这个页面解释了各种字段,MiniDom Python.


Lar*_*ikJ 7

我知道这个问题现在很老了,但我想你可能会更容易使用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
Run Code Online (Sandbox Code Playgroud)

我知道这不是超级特定的,但我刚刚发现它,到目前为止,它比minidom更容易理解(因为这么多节点本质上是空白).

例如,您可以将标签名称和实际文本放在一起,就像您可能期望的那样:

>>> element[0]
<Element currentTime at 40984d0>
>>> element[0].tag
'currentTime'
>>> element[0].text
'2010-04-12 02:45:45'e
Run Code Online (Sandbox Code Playgroud)