Проверить с тремя схемами XML как одна объединенная схема в LXML? - PullRequest
4 голосов
/ 02 марта 2012

Я создаю XML-документ, для которого были предоставлены разные XSD для разных частей (то есть определения для некоторых элементов находятся в определенных файлах, определения для других - в других).

Файлы XSD не относятся друг к другу. Схемы:

  1. http://xmlgw.companieshouse.gov.uk/v2-1/schema/Egov_ch-v2-0.xsd
  2. http://xmlgw.companieshouse.gov.uk/v1-1/schema/forms/FormSubmission-v1-1.xsd
  3. http://xmlgw.companieshouse.gov.uk/v1-1/schema/forms/CompanyIncorporation-v1-2.xsd

Есть ли способ проверки документа по всем схемам с использованием lxml?

Решение здесь - это , а не , чтобы просто проверять индивидуально для каждой схемы, потому что проблема, с которой я сталкиваюсь, состоит в том, что проверка не проходит из-за элементов, не указанных в XSD. Например, при проверке по http://xmlgw.companieshouse.gov.uk/v2-1/schema/Egov_ch-v2-0.xsd я получаю ошибку:

  File "lxml.etree.pyx", line 3006, in lxml.etree._Validator.assertValid (src/lxml/lxml.etree.c:125415)
DocumentInvalid: Element '{http://xmlgw.companieshouse.gov.uk}CompanyIncorporation': No matching global element declaration available, but demanded by the strict wildcard., line 9

Поскольку рассматриваемый документ содержит элемент {http://xmlgw.companieshouse.gov.uk}CompanyIncorporation, который указан не в проверяемом XSD, а в одном из других файлов XSD.

1 Ответ

4 голосов
/ 02 марта 2012

Я полагаю, что вы должны проверять только по Egov_ch-v2-0.xsd, который, по-видимому, определяет конвертовый документ.(Это документ, который вы создаете, верно? Вы не показывали свой XML.)

Эта схема использует <xs:any namespace="##any" minOccurs="0"/> для определения содержимого тела конверта.Однако xsd:any означает , а не означает «игнорировать все содержимое».Скорее это означает «принять что-нибудь здесь».Проверять или игнорировать содержимое контролирует атрибут processContents, который по умолчанию равен strict.Это означает, что любые обнаруженные здесь элементы должны проверять соответствие типам, доступным для схемы.Однако Egov_ch-v2-0.xsd не импортирует CompanyIncorporation-v1-2.xsd, поэтому он не знает об элементе CompanyIncorporation, поэтому документ не проверяется.

Вам необходимо добавить элементы xsd:import в основную схему(Egov_ch-v2-0.xsd) для импорта всех других схем, которые могут использоваться в документе.Вы можете сделать это либо в самом файле xsd, либо программно добавить элементы после синтаксического анализа:

xsd = lxml.etree.parse('http://xmlgw.companieshouse.gov.uk/v2-1/schema/Egov_ch-v2-0.xsd')
newimport = lxml.etree.Element('{http://www.w3.org/2001/XMLSchema}import',
    namespace="http://xmlgw.companieshouse.gov.uk",
    schemaLocation="http://xmlgw.companieshouse.gov.uk/v1-1/schema/forms/CompanyIncorporation-v1-2.xsd")
xsd.getroot().append(newimport)

validator = lxml.etree.XMLSchema(xsd)

Вы можете даже сделать это общим способом с помощью функции, которая принимает список путей к схемам ивозвращает список xsd:import операторов с namespace и schemaLocation, заданных синтаксическим анализом targetNamespace.

(Кроме того, вы, вероятно, должны загрузить эти документы схемы и ссылаться на них с путями файловой системы, а не загружатьих по сети.)

...