2010-02-18 5 views
1

저는 XML과 파이썬에 대한 기본적인 이해를 가지고 있으며 성공과 함께 minidom을 사용하고 있습니다. XML 파일에서 원하는 값을 얻을 수없는 상황이 발생했습니다. 다음은 기존 파일의 기본 구조입니다.파이썬에서 XML 파일의 값을 필터링하는 방법

<localization> 
    <b n="Stats"> 
     <l k="SomeStat1"> 
      <v>10</v> 
     </l> 
     <l k="SomeStat2"> 
      <v>6</v> 
     </l> 
    </b> 
    <b n="Levels"> 
     <l k="Level1"> 
      <v>Beginner Level</v> 
     </l> 
     <l k="Level2"> 
      <v>Intermediate Level</v> 
     </l> 
    </b> 
</localization> 

수십 개의 어린이가있는 <b> 태그가 약 15 개 있습니다. 레벨 번호가 주어지면 해당 레벨의 <v> 노드를 찾습니다. 나는 이것에 대해 어떻게 생각하는지 모른다.

+0

예제를 포함한 자세한 정보가 도움이 될 수 있습니다. 예제 XML 데이터가 주어지면 레벨 번호가 1 일 때 ''노드가 필요하십니까? –

답변

1

당신이 정말로에만 <v> 태그 (즉, 내가 당신의 질문을 이해 방법), 당신은 DOM 함께 할 수있는지고 한 후 특정 "K"속성과 <l> 태그 검색하고 걱정하는 경우 :

from xml.dom.minidom import parseString 

xmlDoc = parseString("""<document goes here>""") 
lNodesWithLevel2 = [lNode for lNode in xmlDoc.getElementsByTagName("l") 
        if lNode.getAttribute("k") == "Level2"] 

matchingVNodes = map(lambda lNode: lNode.getElementsByTagName("v"), lNodesWithLevel2) 

print map(lambda vNode: vNode.firstChild.nodeValue, matchingVNodes) 
# Prints [u'Intermediate Level'] 

그게 무슨 뜻인가요?

+0

나는이 해결책을 좋아한다. 이런 식으로 생각하지도 않았을 것입니다. – DewBoy3d

2
#!/usr/bin/python 

from xml.dom.minidom import parseString 

xml = parseString("""<localization> 
    <b n="Stats"> 
     <l k="SomeStat1"> 
      <v>10</v> 
     </l> 
     <l k="SomeStat2"> 
      <v>6</v> 
     </l> 
    </b> 
    <b n="Levels"> 
     <l k="Level1"> 
      <v>Beginner Level</v> 
     </l> 
     <l k="Level2"> 
      <v>Intermediate Level</v> 
     </l> 
    </b> 
</localization>""") 

level = 1 
blist = xml.getElementsByTagName('b') 
for b in blist: 
    if b.getAttribute('n') == 'Levels': 
     llist = b.getElementsByTagName('l') 
     l = llist.item(level) 
     v = l.getElementsByTagName('v') 
     print v.item(0).firstChild.nodeValue; 
     #prints Intermediate Level 
0
level = "Level"+raw_input("Enter level number: ") 
content= open("xmlfile").read() 
data= content.split("</localization>") 
for item in data: 
    if "localization" in item: 
     s = item.split("</b>") 
     for i in s: 
      if """<b n="Levels">""" in i: 
       for c in i.split("</l>"): 
        if "<l" in c and level in c: 
         for v in c.split("</v>"): 
          if "<v>" in v: 
           print v[v.index("<v>")+3:] 
4

XML 문서의 일부분을 처리하는 언어 인 XPATH를 사용하는 것이 좋습니다.

여기는 대답 lxml.etree을 사용하는 답변이며 xpath을 지원합니다.

>>> data = """ 
... <localization> 
...  <b n="Stats"> 
...   <l k="SomeStat1"> 
...    <v>10</v> 
...   </l> 
...   <l k="SomeStat2"> 
...    <v>6</v> 
...   </l> 
...  </b> 
...  <b n="Levels"> 
...   <l k="Level1"> 
...    <v>Beginner Level</v> 
...   </l> 
...   <l k="Level2"> 
...    <v>Intermediate Level</v> 
...   </l> 
...  </b> 
... </localization> 
... """ 
>>> 
>>> from lxml import etree 
>>> 
>>> xmldata = etree.XML(data) 
>>> xmldata.xpath('/localization/b[@n="Levels"]/l[@k=$level]/v/text()',level='Level1') 
['Beginner Level'] 
+0

그냥 웃어 보았습니다. 다른 해결책보다 좀 더 효율적이라고 생각했기 때문에 이것을 시도했습니다. 이 질문에 대한 질문이 하나 있는데, 어떻게 xpath에 [[ ']] (괄호와 따옴표) 값을 반환 할 수 있습니까? – DewBoy3d

+0

'xpath' 메쏘드는 문자열 객체의'list'를 리턴합니다. 쿼리와 일치하는 항목이 없으면 목록의 길이가 0이되거나 일치 항목이 두 개 이상인 경우 목록의 길이가 1보다 커집니다. 반환 객체의 len 또는'result [0]'을 검사하고'IndexError'를 잡을 준비가되어 있어야합니다. 나는 문자열 객체에 관해서'따옴표없이'무엇을 말할 지 모르겠습니다. 아마도'print result [0]'? – MattH

0

당신이 BeautifulSoup 라이브러리 (당신이 할 수 없었다?)이 죽은 - 간단한 코드로 끝낼 수 있었다 사용할 수있는 경우 :

from BeautifulSoup import BeautifulStoneSoup 

def get_it(xml, level_n): 
    soup = BeautifulStoneSoup(xml) 
    l = soup.find('l', k="Level%d" % level_n) 
    return l.v.string 

if __name__ == '__main__': 
    print get_it(1) 

그것은 당신이 제공 한 예를 들어 XML에 대한 Beginner Level 인쇄합니다.

+0

이것은 확실히 아름답지만이 프로젝트에 다른 라이브러리를 사용하고 싶지 않았습니다. 거의 완료되었으므로 돌아가서이 새로운 라이브러리를 수용하기 위해 다른 모든 것을 변경하고 싶습니다. 시간이 없습니다. – DewBoy3d

관련 문제