2012-02-27 76 views
1

我試圖用Python的薩克斯庫要求獲得孩子們標記的名稱。我使用ContentHandler作爲處理程序。任何人都有一個想法如何獲得標籤名稱?蟒蛇薩克斯XML名稱標籤

假設我們的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; 

如何獲得字符串「child1」和「的child2」假設我只知道父母的名字?

回答

6

SAX風格的解析器要求你保持你所需要的所有狀態,如哪些標籤,你見過的軌道。在nminimum,你需要做的是寫一個startElement()處理程序設置一個標誌,當它看到一個<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.minidomlxml,是一個更容易爲這些類型的任務的工作,因爲它會跟蹤你的元素之間的關係。這樣的解析器可能是你需要一個更好的選擇:

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,你的查詢是單一的Python聲明(其中包含兩個過程循環, ,但這是一個單一的聲明)。用SAX風格的解析器不能真正達到這種簡潔程度。

現在,SAX風格的解析器運行速度更快,比DOM解析器,這在十年前是重要的內存更少,但差距是非常小的現代處理器,尤其是在短小的文件。程序員的時間更有價值。