Следующие xs: включить при разборе XSD как XML с lxml в Python

1

Итак, моя проблема в том, что я пытаюсь сделать что-то мало-ортодоксальное. У меня сложный набор XSD файлов. Однако я не хочу использовать эти файлы XSD для проверки XML файла; Я хочу проанализировать эти XSD как XML и опросить их так же, как и обычный файл XML. Это возможно, потому что XSD являются действительными XML. Я использую lxml с Python3.

Проблема, с которой я столкнулась, заключается в следующем:

<xs:include schemaLocation="sdm-extension.xsd"/>

Если я инструктирую lxml создать XSD для проверки следующим образом:

schema = etree.XMLSchema(schema_root)

эта зависимость будет разрешена (файл существует в том же каталоге, что и тот, который я только что загрузил). ОДНАКО, я рассматриваю их как XML так, правильно, lxml просто рассматривает это как обычный элемент с атрибутом и не следует за ним.

Есть ли простой или правильный способ расширения lxml, чтобы я мог иметь такое же или подобное поведение, например,

<xi:include href="metadata.xml" parse="xml" xpointer="title"/>

Я мог бы, конечно, создать отдельный XML файл вручную, включающий все зависимости в схеме XSD. Возможно, это решение?

Теги:
xsd

2 ответа

0

Попробуйте следующее:

def validate_xml(schema_file, xml_file):
    xsd_doc = etree.parse(schema_file)
    xsd = etree.XMLSchema(xsd_doc)
    xml = etree.parse(xml_file)
    return xsd.validate(xml)
0

Итак, кажется, что один из вариантов - использовать метод xi: xinclude и создать отдельный XML файл, который включает все XSD, которые я хочу проанализировать. Что-то вроде:

<fullxsd>
<xi:include href="./xsd-cdisc-sdm-1.0.0/sdm1-0-0.xsd" parse="xml"/>
<xi:include href="./xsd-cdisc-sdm-1.0.0/sdm-ns-structure.xsd" parse="xml"/>
</fullxsd>

Затем используйте некоторый lxml вдоль строк

 def combine(xsd_file):
      with open(xsd_file, 'rb') as f_xsd:
          parser = etree.XMLParser(recover=True, encoding='utf-8',remove_comments=True,                    remove_blank_text=True)

          xsd_source = f_xsd.read()
          root = etree.fromstring(xsd_source, parser)
          incl = etree.XInclude()
          incl(root)

          print(etree.tostring(root, pretty_print=True))

Это не идеальный, но он кажется правильным. Я посмотрел на пользовательские парсеры URI в lxml, но это означало бы фактически изменение XSD, которое кажется более беспорядочным.

  • 0
    На самом деле есть проблема с этим подходом, когда речь идет о пространствах имен. один XSD может ссылаться на что-либо в другом XSD-файле через пространство имен. Так что простое использование xinclude само по себе не поможет.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню