Python으로 minidom으로 요소 값 가져 오기


109

Python에서 Eve Online API 용 GUI 프런트 엔드를 만들고 있습니다.

서버에서 XML 데이터를 성공적으로 가져 왔습니다.

"이름"이라는 노드에서 값을 가져 오려고합니다.

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

이것은 노드를 찾는 것처럼 보이지만 출력은 다음과 같습니다.

[<DOM Element: name at 0x11e6d28>]

노드의 값을 인쇄하려면 어떻게해야합니까?


5
대부분의 "미니 덤"질문에 대한 답이 "ElementTree 사용"인 것처럼 보이기 시작했습니다.
Warren P

답변:


156

그것은 단지

name[0].firstChild.nodeValue

4
내가 할 때 name [0] .nodeValue는 "None"을 돌려주고, 테스트하기 위해 name [0] .nodeName을 전달했고 올바른 "name"을주었습니다. 어떤 아이디어?
RailsSon

28
name [0] .firstChild.nodeValue는 어떻습니까?
eduffy

7
xml-generator의 구현 세부 정보에 의존하지 않는다는 점에 유의하십시오. 첫 번째 자식임을 보장이 없습니다 텍스트 노드 나 하나 개 이상의 자식 노드가있을 수있는 모든 경우에 텍스트 노드는.
Henrik Gustafsson

53
왜 <name> Smith </ name>의 nodeValue가 "Smith"가 아닌 라이브러리를 디자인할까요?! 그 작은 너겟은 내 머리카락을 찢는 데 30 분이 걸렸다. 나는 지금 대머리이다. 고마워요, 미니 덤.
Assaf Lavie

10
html과 함께 작동하도록 설계 한 방식 때문입니다.이 <nodeA> Some Text <nodeinthemiddle> __ complex__structure __ </ nodeinthemiddle> 좀 더 많은 텍스트 </ nodeA>와 같은 요소를 허용합니다.이 경우에는 nodeA의 nodeValue라고 생각하십니까? 복잡한 구조를 포함한 모든 텍스트 또는 단순히 2 개의 텍스트 노드와 중간 노드를 포함해야합니다. 그것을 보는 가장 좋은 방법은 아니지만 그들이 왜 그것을했는지 알 수 있습니다.
Josh Mc

60

당신이 원하는 텍스트 부분이라면 아마 이런 것입니다.

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 (). 공백을 개행 문자로 대체하거나 아무것도 사용하지 않을 수 있습니다.


12

이런 식으로 사용할 수 있습니다.

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

8

나는이 질문이 지금 꽤 오래되었다는 것을 알고 있지만 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

8

위의 대답은 정확합니다.

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에서 설명합니다.


2

비슷한 경우가 있었는데 나를 위해 일한 것은 다음과 같습니다.

name.firstChild.childNodes [0] .data

XML은 간단해야하고 정말 그렇고 파이썬의 미니 덤이 왜 그렇게 복잡했는지 모르겠습니다 ...하지만 어떻게 만들어 졌는지 모르겠습니다.


2

다음은 여러 노드에 대한 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

질문에 대한 답변을 받았으며, 저의 기여는 초보자를 혼란스럽게 할 수있는 한 가지를 명확히하는 데 있습니다.

제안 및 정답 중 일부는 사용 firstChild.data되었고 다른 일부는 firstChild.nodeValue대신 사용 되었습니다. 그들 사이의 차이점이 궁금한 경우은 .NET nodeValue의 별칭 일 뿐이 므로 동일한 작업을 수행한다는 것을 기억해야합니다 data.

내 진술에 대한 참조 는 minidom소스 코드 에 대한 주석으로 찾을 수 있습니다 .

# nodeValue은 별칭입니다.data


0

나무이고 중첩 된 요소가있을 수 있습니다. 시험:

def innerText(self, sep=''):
    t = ""
    for curNode in self.childNodes:
        if (curNode.nodeType == Node.TEXT_NODE):
            t += sep + curNode.nodeValue
        elif (curNode.nodeType == Node.ELEMENT_NODE):
            t += sep + curNode.innerText(sep=sep)
    return t
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.