2012-02-27 2 views
1

python의 sax 라이브러리로 children 태그의 이름을 얻으려고합니다. 나는 ContentHandler를 핸들러로 사용하고있다. 누구든지 태그 이름을 얻는 방법을 알고 있습니까?python sax xml children 태그의 이름

은의 우리의 XML 문서가 보이는 가정하자 같은 :

<root> 
    <parent> 
     <child1>X</child1> 
     <child2>Y</child2> 
    </parent> 
</root> 

그리고 이제 우리는 핸들러 템플릿을 사용하는 가정하자 :

class parserSAXHandler(handler.ContentHandler): 

    def __init__(self): 
       pass; 
    def startElement(self, name, attrs): 
       pass; 
    def endElement(self,name): 
       pass; 
    def characters(self, content): 
       pass; 

가 어떻게 문자열을 얻을 수있다 "자식 1"과 "자식 2" 나는 부모의 이름 만 알고 있다고 가정 할 때?

답변

6

SAX 스타일 파서는 사용자가 본 태그와 같이 필요한 모든 상태를 추적해야합니다. 최소값 일 경우, <parent> 태그를 볼 때 플래그를 설정하고 닫는 태그를 볼 때 해당 플래그를 지우는 endElement() 핸들러를 작성하십시오. startElement() 처리기는 또한이 플래그가 설정된 경우 목록에 표시된 태그를 누적해야합니다.

class parserSAXHandler(handler.ContentHandler): 

    def __init__(self): 
     self.parentflag = False 
     self.childlist = [] 

    def startElement(self, name, attrs): 
     if name == "parent": 
      self.parentflag = True 
     elif self.parentflag: 
      self.childlist.append(name) 

    def endElement(self,name): 
     if name == "parent": 
      self.parentflag = False 

분석 한 후, 인스턴스의 childlist 속성은 당신이 원하는 목록을해야합니다.

<child> 태그 안에 추가 태그가 중첩되어 있고 태그가없는 경우 더 정교한 로직이 필요할 수 있습니다.은 이러한 태그 이름을 원합니다. 그대로 모든 레벨의 <parent> 컨테이너 안에 중첩 된 태그가 포함됩니다. 중첩을 추적하는 가장 쉬운 방법은 스택을 사용하는 것입니다. 각 시작 태그를 누르고 각 닫는 태그를 팝한 다음 parent이 스택 맨 위에 있는지 확인할 수 있습니다.

class parserSAXHandler(handler.ContentHandler): 

    def __init__(self): 
     self.tagstack = [] 
     self.childlist = [] 

    def startElement(self, name, attrs): 
     if self.tagstack[-1] == "parent": 
      self.childlist.append(name) 
     self.tagstack.append(name) 

    def endElement(self,name): 
     if name == self.tagstack[-1]: 
      self.tagstack.pop() 
     else: 
      raise SAXParseException("tag closed without being open") 

는 DOM 스타일의 파서는, 같은 xml.dom.minidom 또는 lxml, 그것은 당신을위한 요소 사이의 관계를 추적하기 때문에 작업의 이러한 종류의 작업을하는 것이 훨씬 더 쉽다. 이러한 파서는 사용자의 요구에 더 나은 선택이 될 수 있습니다

from xml.dom.minidom import parseString 

xml = """ 
    <root> 
     <parent> 
      <child1>X</child1> 
      <child2>Y</child2> 
     </parent> 
    </root> 
""" 

dom = parseString(xml) 
children = [c.localName for p in dom.getElementsByTagName("parent") 
      for c in p.childNodes if c.nodeType == c.ELEMENT_NODE] 
당신은 minidom 모듈이 우리의 XML을 구문 분석되면, 쿼리는 물론, 두 개의 루프를 포함하는 하나의 파이썬 문 (인 것을 알 수 있습니다

그럼에도 불구하고 하나의 성명서입니다.) SAX 스타일 구문 분석기로는 그 수준의 간결함을 실제로 달성 할 수 없습니다.

이제 SAX 스타일 파서는 DOM 파서보다 빠르며 10 년 전에는 중요하지 않았던 메모리를 사용하지만 현대 프로세서, 특히 작은 문서에서는 그 차이가 훨씬 작습니다. 프로그래머 시간은 훨씬 더 가치가 있습니다.

관련 문제