Найти элементы на основе типа xsd с помощью lxml - PullRequest
7 голосов
/ 30 марта 2010

Я пытаюсь получить список элементов с определенным типом xsd с помощью lxml 2.x и не могу понять, как пройти 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 голосов
/ 30 марта 2010

На самом деле единственная специальная поддержка, которую lxml имеет для XML-схемы, как видно здесь , - это сказать вам, является ли какой-то документ действительным в соответствии с какой-либо схемой или нет. Что-нибудь более сложное вам придется делать самостоятельно.

Я бы подумал, что это должен быть относительно простой двухэтапный процесс - получить все элементы 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 для поиска в документе должно проверять каждый элемент, поэтому, если вы можете усилить его, чтобы просмотреть только тот раздел документа, который вас интересует, он пойдет быстрее.

...