2009-12-23 2 views
14

ElementTree를 사용하여 NS 속성에 어떻게 액세스 할 수 있습니까?Python Elementree로 XMLNS 속성에 액세스 하시겠습니까?

<data xmlns="http://www.foo.net/a" xmlns:a="http://www.foo.net/a" book="1" category="ABS" date="2009-12-22"> 

내가 다시 없음, 종류와 날짜, 감사 어떤 도움도 괜찮 얻을 ('의 xmlns') root.get하려고 ..

+3

나는 당신의 질문에 대답 할 수 없다. 그러나 며칠 동안이 단점에 대해 고민하면서 나는 현재의 ElementTree API를 사용하는 것이 불가능하다고 주장 할 준비가되어있다. 내 응용 프로그램에서 xmlns : xlink 특성이 이미 루트 요소에 있었는지 여부를 감지하고 필요하지 않으면 추가해야했습니다. xmlns 속성이 이미 존재하는지 테스트하는 것은 불가능합니다. ElementTree는 시도 할 경우 두 번 추가하면됩니다. 대부분의 XML 소비자에서 동일한 요소에 0 또는 2 개의 동일한 xmlns 특성이 오류를 발생시키기 때문에 ElementTree를 사용하기가 매우 어렵습니다. –

답변

14

내가 element.tag 생각 다음으로

당신이 찾고있는 것입니다. 예제에 슬래시가 없으므로 불균형으로 해석되지 않습니다. 내 예제에 하나 추가했습니다. 당신은 단지의 xmlns URI를 알고 싶다면

>>> from xml.etree import ElementTree as ET 
>>> data = '''<data xmlns="http://www.foo.net/a" 
...     xmlns:a="http://www.foo.net/a" 
...     book="1" category="ABS" date="2009-12-22"/>''' 
>>> element = ET.fromstring(data) 
>>> element 
<Element {http://www.foo.net/a}data at 1013b74d0> 
>>> element.tag 
'{http://www.foo.net/a}data' 
>>> element.attrib 
{'category': 'ABS', 'date': '2009-12-22', 'book': '1'} 

, 당신은 같은 기능 그것을 나눌 수 있습니다 :

def tag_uri_and_name(elem): 
    if elem.tag[0] == "{": 
     uri, ignore, tag = elem.tag[1:].partition("}") 
    else: 
     uri = None 
     tag = elem.tag 
    return uri, tag 

을 훨씬 더 네임 스페이스와 자격을 갖춘 이름에 들어 ElementTree에, effbot's examples를 참조하십시오.

+11

라이브러리에 이와 같은 기능이없는 이유는 무엇입니까? 네임 스페이스가있는 모든 xml 파일에서 필요로하는 것처럼 보입니다. 나는 그것을 놓치고 있니? – Clutch

+0

@ clutch 나는 똑같은 것을 궁금해하고있다. 누구나 이유를 아나요? – Santa

+0

@rednaw, 나는 분할이 더 낫다고 확신하지 않는다. 분할은 정확히 세 요소의 튜플을 반환하도록 보장되며, split은 임의의 수의 요소를 반환 할 수 있습니다. 실제로는 문법적으로 하나의 닫는 중괄호를 제외하고는 아무 것도 가질 수 없지만 여전히 그렇습니다. 나는 파티션이 더 좋다고 생각한다. –

7

이펙트 네임 스페이스 문서/예제를 살펴보십시오. 구체적으로는 parse_map 기능입니다. 특정 요소에 적용되는 접두사/URI 매핑을 포함하는 각 요소에 * ns_map * 속성을 추가하는 방법을 보여줍니다.

그러나 이는 모든 요소에 ns_map 속성을 추가합니다. 필자의 필요에 따라 요소 조회를 쉽게하고 하드 코딩하지 않는 데 사용되는 모든 네임 스페이스의 글로벌 맵을 원했습니다. XML 파일을 구문 분석하고 네임 스페이스 매핑으로 딕셔너리를 얻을 수 있습니다 이것으로

import elementtree.ElementTree as ET 

def parse_and_get_ns(file): 
    events = "start", "start-ns" 
    root = None 
    ns = {} 
    for event, elem in ET.iterparse(file, events): 
     if event == "start-ns": 
      if elem[0] in ns and ns[elem[0]] != elem[1]: 
       # NOTE: It is perfectly valid to have the same prefix refer 
       #  to different URI namespaces in different parts of the 
       #  document. This exception serves as a reminder that this 
       #  solution is not robust. Use at your own peril. 
       raise KeyError("Duplicate prefix with different URI found.") 
      ns[elem[0]] = "{%s}" % elem[1] 
     elif event == "start": 
      if root is None: 
       root = elem 
    return ET.ElementTree(root), ns 

:

는 여기에 내가 무엇을 최대 온입니다. 그래서, 당신은 ("my.xml") 다음과 같은 XML 파일이있는 경우 :

<?xml version="1.0" encoding="UTF-8" ?> 
<rss version="2.0" 
xmlns:content="http://purl.org/rss/1.0/modules/content/" 
xmlns:dc="http://purl.org/dc/elements/1.1/"\ 
> 
<feed> 
    <item> 
    <title>Foo</title> 
    <dc:creator>Joe McGroin</dc:creator> 
    <description>etc...</description> 
    </item> 
</feed> 
</rss> 

당신은 XML을 namepaces를 사용하고 직류와 같은 요소에 대한 정보를 얻을 수있을 것입니다 : 작성자 :

>>> tree, ns = parse_and_get_ns("my.xml") 
>>> ns 
{u'content': '{http://purl.org/rss/1.0/modules/content/}', 
u'dc': '{http://purl.org/dc/elements/1.1/}'} 
>>> item = tree.find("/feed/item") 
>>> item.findtext(ns['dc']+"creator") 
'Joe McGroin' 
+0

귀하는 http://stackoverflow.com/questions/13018024/converting-my-python-script-from-lxml-to-xml-etree/13019393#13019393에서 내 게시물에 답변했습니다. –

관련 문제