2017-09-07 13 views
0

iterfind를 사용하여 모든 IPv6 주소 요소를 구문 분석하려고합니다. 일치하는 문자열이 맞다고 생각했지만 결과가 표시되지 않습니다. 깊은 XML 파일을 파싱하는 것에 익숙하지 않아서이 방법이 최선의 방법인지 질문하기 시작했습니다.ElementTree의 iterfind를 사용하여 XML 파싱을 깊게 수행

import requests 
import xml.etree.ElementTree as ET 

r = requests.get('https://support.content.office.net/en-us/static/O365IPAddresses.xml') 

root = ET.fromstring(r.text) 

for node in root.iterfind(".//products/product/[@name='o365']/addresslist/[@type='IPv6']"): 
    data = [] 
    for d in node.getchildren(): 
     if d.text: 
      data.append(d.text) 
    print ' '.join(data) 

답변

2

xpath 표현이 올바른지 확인하십시오.

>>> r = requests.get('https://support.content.office.net/en-us/static/O365IPAddresses.xml') 
>>> root = ET.fromstring(r.text) 

당신이 당신의 XPath 식, .//products의 시작을 검색하면, 당신은 무엇을합니까 : 시작?

>>> root.findall('.//products/product') 
[] 

빈 목록이 표시됩니다. 즉, 표현식에 문제가 있음을 의미합니다. 당신의 트리의 루트가 products 요소이기 때문이다 :

>>> root 
<Element 'products' at 0x7f16be5a9450> 

그래서 관계의 계층의 첫 번째 수준은 product 될 것입니다 :

>>> root.findall('product') 
[<Element 'product' at 0x7f16be5a9490>, <Element 'product' at 0x7f16be0e4190>, ...] 

당신이 당신의 전체 표현으로이 다시 대체 할 경우, 우리가 얻을 :

>>> root.findall("product/[@name='o365']/addresslist/[@type='IPv6']") 
[<Element 'addresslist' at 0x7f16be5a94d0>] 

훨씬 좋아 보입니다.

예제 코드에서 해당 식을 사용하면 합리적인 출력이 생성됩니다.