lxml проверяет xml при записи в файл и читает обратно, но не проверяет дерево DOM, из которого генерируется файл - PullRequest
3 голосов
/ 11 декабря 2011

Я использую lxml, чтобы сгенерировать xml и проверить его. Я обнаружил, что когда я пытаюсь использовать валидатор XSD для проверки дерева DOM, валидатор жалуется, что не распознает корневой элемент; напротив, когда это дерево преобразуется в текст, записывается в файл, читается и анализируется в дереве DOM, распознается корневой элемент нового дерева DOM. Надеюсь, что нижеприведенное проиллюстрирует, что я имею в виду.

Мой вопрос: почему это происходит? Есть ли способ получить оригинальное дерево DOM для проверки, кроме рендеринга в строку и повторного анализа?

>>> from lxml import etree
>>> import io
>>> validator = etree.XMLSchema(etree.parse(io.open('mainapp/xsd/forms/CompanyIncorporation-v2-6.xsd')))
>>> c = CompanyUK.objects.all()[5]
>>> cotree = xml.Company.generate_company_incorporation_tree(c)
>>> cotree
<Element CompanyIncorporation at 0x38f2750>
>>> validator.assertValid(cotree)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "lxml.etree.pyx", line 3006, in lxml.etree._Validator.assertValid (src/lxml/lxml.etree.c:125415)
DocumentInvalid: Element 'CompanyIncorporation': No matching global declaration available for the validation root.
>>> cott = etree.ElementTree(cotree)
>>> validator.assertValid(cott)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "lxml.etree.pyx", line 3006, in lxml.etree._Validator.assertValid (src/lxml/lxml.etree.c:125415)
DocumentInvalid: Element 'CompanyIncorporation': No matching global declaration available for the validation root.
>>> xmlfile = open("xmlfile", "w")
>>> xmlfile.write(etree.tostring(cott))
>>> xmlfile.flush()
>>> xmlfile.close()
>>> xmlfile = open("xmlfile", "r")
>>> ptree = etree.parse(xmlfile)
>>> validator.assertValid(ptree)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "lxml.etree.pyx", line 3006, in lxml.etree._Validator.assertValid (src/lxml/lxml.etree.c:125415)
DocumentInvalid: Element '{http://xmlgw.companieshouse.gov.uk}Country': [facet 'enumeration'] The value 'EW' is not an element of the set {'GB-ENG', 'GB-WLS', 'GB-SCT', 'GB-NIR', 'GBR', 'UNDEF'}., line 1
>>> etree.tostring(ptree) == etree.tostring(cott)
True
>>> validator.assertValid(etree.parse(io.StringIO(etree.tounicode(ptree))))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "lxml.etree.pyx", line 3006, in lxml.etree._Validator.assertValid (src/lxml/lxml.etree.c:125415)
DocumentInvalid: Element '{http://xmlgw.companieshouse.gov.uk}Country': [facet 'enumeration'] The value 'EW' is not an element of the set {'GB-ENG', 'GB-WLS', '
GB-SCT', 'GB-NIR', 'GBR', 'UNDEF'}., line 1
>>> validator.assertValid(etree.parse(io.StringIO(etree.tounicode(cot))))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
NameError: name 'cot' is not defined
>>> validator.assertValid(etree.parse(io.StringIO(etree.tounicode(cott))))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "lxml.etree.pyx", line 3006, in lxml.etree._Validator.assertValid (src/lxml/lxml.etree.c:125415)
DocumentInvalid: Element '{http://xmlgw.companieshouse.gov.uk}Country': [facet 'enumeration'] The value 'EW' is not an element of the set {'GB-ENG', 'GB-WLS', '
GB-SCT', 'GB-NIR', 'GBR', 'UNDEF'}., line 1
>>> validator.assertValid(etree.parse(io.BytesIO(etree.tostring(cott))))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "lxml.etree.pyx", line 3006, in lxml.etree._Validator.assertValid (src/lxml/lxml.etree.c:125415)
DocumentInvalid: Element '{http://xmlgw.companieshouse.gov.uk}Country': [facet 'enumeration'] The value 'EW' is not an element of the set {'GB-ENG', 'GB-WLS', '
GB-SCT', 'GB-NIR', 'GBR', 'UNDEF'}., line 1
>>>

Как вы можете видеть выше, проверка продвигается дальше с версией, проанализированной с диска, даже если они отображаются в одну и ту же строку (и аналогично, проверка выходит за пределы корневого элемента после обращения к строке и повторно анализируется в DOM дерево). Итак, что может быть причиной этого?

...