2011-05-04 5 views
0

xpath를 사용하여 Python의 libxml2로 XML 컨텐트를 파싱하려면, this examplethat tutorial을 따릅니다.Python : libxml2 xpath는 빈리스트를 반환합니다.

<?xml version="1.0" encoding="UTF-8"?> 
<feed xmlns="http://purl.org/atom/ns#" version="0.3"> 
<title>Gmail - Inbox for [email protected]</title> 
<tagline>New messages in your Gmail Inbox</tagline> 
<fullcount>1</fullcount> 
<link rel="alternate" href="http://mail.google.com/mail" type="text/html"/> 
<modified>2011-05-04T18:56:19Z</modified> 
</feed> 

이 XML은 "원자"라는 파일에 저장되고, 나는 다음과 같은 시도 : XML 파일은 당신이 빈 목록을 반환 볼 수 있듯이 이제

>>> import libxml2 
>>> myfile = open('/pathtomyfile/atom', 'r').read() 
>>> xmldata = libxml2.parseDoc('myfile') 
>>> data.xpathEval('/fullcount') 
[] 
>>> 

. xpath를 제공 할 수있을지라도 빈 목록을 반환합니다. 이제

>>>> data.xpathEval('//*') 
[<xmlNode (feed) object at 0xb73862cc>, <xmlNode (title) object at 0xb738650c>, <xmlNode (tagline) object at 0xb73865ec>, <xmlNode (fullcount) object at 0xb738660c>, <xmlNode (link) object at 0xb738662c>, <xmlNode (modified) object at 0xb738664c>] 

내가 XPath는이 "fullcount"노드를 찾거나하지 않는 이유 위의 작동 예에서 판단, 이해가 안 : 내가 * 와일드 카드를 사용할 경우, 나는 모든 노드의 목록을 어떤 다른 : 나는 결국 같은 구문을 사용하고 있습니다 ...

어떤 생각이나 제안? 감사. 첫째

+1

왜 lxml을 사용하지 않습니까? –

+0

그리고 왜해야합니까? :) 나는 지금 lxml 의사를보고 있습니다. 감사. – Benjamin

+0

그것은 libxml2에 대한 바인딩입니다. 대체 바인딩이 있음을 알지 못했지만, lxml은 매우 직관적입니다. –

답변

2

당신이 노드에서 안뜨기 네임 스페이스를 지정해야하기 때문에 귀하의 XPath가 실패 :

import libxml2 
tree = libxml2.parseDoc(data) 
xp = tree.xpathNewContext() 
xp.xpathRegisterNs("purl", "http://purl.org/atom/ns#") 
print xp.xpathEval('//purl:fullcount') 

결과 :

[<xmlNode (fullcount) object at 0x7fbbeba9ef80>] 

(또한 : lxml을 확인하십시오. 더 멋진 인터페이스입니다.)

+0

실무 답변 thanks :) 자, _purl 네임 스페이스 란 무엇입니까? 설명해 주시겠습니까? – Benjamin

+0

@Benjamin 피드 태그에 정의 된 문서의 기본 네임 스페이스입니다 :''. 즉, 문서의 모든 노드를 해당 네임 스페이스에 할당하는 바로 가기입니다. 따라서 libxml2에이 문서의 노드에 대해 물어볼 때마다 네임 스페이스를 포함하지 못하면 어떤 의미인지 알 수 없습니다. :-) – samplebias

+0

고마워, 나는 네임 스페이스의 개념에 익숙하지 않다. 네임 스페이스가 제공하는 정의는 무엇입니까? – Benjamin

0

:

/fullcount는 절대 경로, 그래서 그것은 요소가 <feed> 요소 내에서 사실상 문서의 루트에서 <fullcount> 요소를 찾고 있어요.

둘째 :

당신은 네임 스페이스를 지정해야합니다. 이것은 당신이 lxml으로 어떻게 할 것입니다 :

import lxml.etree as etree 

tree = etree.parse('/pathtomyfile/atom') 

fullcounts = tree.xpath('//ns:fullcount', 
       namespaces={'ns': "http://purl.org/atom/ns#"}) 

print etree.tostring(fullcounts[0]) 

당신을 줄 것이다 :

<fullcount xmlns="http://purl.org/atom/ns#">1</fullcount>