使用lxml根据xsd类型查找元素

8 投票
1 回答
4472 浏览
提问于 2025-04-15 21:01

我正在尝试使用 lxml 2.x 获取具有特定 xsd 类型的元素列表,但我不知道怎么在 xsd 中查找特定类型。

这是一个模式的例子:

<xsd:element name="ServerOwner" type="srvrs:string90" minOccurs="0">
<xsd:element name="HostName" type="srvrs:string35" minOccurs="0">

这是一个 xml 数据的例子:

<srvrs:ServerOwner>John Doe</srvrs:ServerOwner>
<srvrs:HostName>box01.example.com</srvrs:HostName>

理想的函数应该像这样:

    elements = getElems(xml_doc, 'string90')

    def getElems(xml_doc, xsd_type):
      ** xpath or something to find the elements and build a dict
      return elements

1 个回答

5

其实,lxml对XML Schema的支持主要就是告诉你某个文档是否符合某个模式,具体可以在这里查看。如果你想做更复杂的事情,就得自己动手了。

我觉得这个过程应该比较简单,可以分为两个步骤。首先,找出模式中所有符合你关心的类型的xsd:element元素,然后看看它们的名字:

def getElems(schemaDoc, xmlDoc, typeName):
    names = schemaDoc.xpath("//xsd:element[@type = $n]/@name",
                            namespaces={"xsd": 
                                        "http://www.w3.org/2001/XMLSchema"},
                            n=typeName)

接着,从文档中获取所有这些名字对应的元素。

    elements = []
    for name in names: 
        namedElements = xmlDoc.xpath("//*[local-name() = $name]", name=name)
        elements.extend(namedElements)

现在,你就有了一份包含与模式中类型匹配的名字的元素列表。

    return elements

需要注意的是,查找文档的xpath表达式必须查看每一个元素,所以如果你能把范围缩小到你关心的文档部分,这样会更快。

撰写回答