Skip to main content
 首页 » 编程设计

子标签的python sax xml名称

2025年05月04日15落叶无声

我正在尝试使用 python 的 sax 库获取子标签的名称。我使用 ContentHandler 作为处理程序。任何人都知道如何获取标签名称?

假设我们的 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; 

假设我只知道 parent 的名字,如何获取字符串“child1”和“child2”?

请您参考如下方法:

SAX 风格的解析器要求您跟踪您需要的所有状态,例如您看到了哪些标签。至少,您需要做的是写一个 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.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,您的查询是一个单个 Python 语句(当然,它包含两个循环,但它仍然是一个语句)。使用 SAX 样式的解析器无法真正达到那种简洁程度。

现在,SAX 样式的解析器比 DOM 解析器更快,占用的内存更少,这在十年前很重要,但现代处理器上的差距要小得多,尤其是在小文档上。程序员的时间更有值(value)。