Проверка XML с использованием пространств имен в Schematron с использованием lxml в Python - PullRequest
4 голосов
/ 22 октября 2019

Мне не удалось получить lxml валидатор Schematron для распознавания пространств имен. Проверка корректно работает в коде без пространств имен.

Это для Python 3.7.4 и lxml 4.4.0 на MacOS 10.15

Вот файл схемы

<?xml version='1.0' encoding='UTF-8'?>
<schema xmlns="http://purl.oclc.org/dsdl/schematron"
  xmlns:ns1="http://foo">
  <pattern>
    <rule context="//ns1:bar">
      <assert test="number(.) = 2">
       bar must be 2
      </assert>
    </rule>
  </pattern>
</schema>

ивот XML-файл

<?xml version="1.0" encoding="UTF-8"?>
<zip xmlns:ns1="http://foo">
    <ns1:bar>3</ns1:bar>
</zip>

вот код Python

from lxml import etree, isoschematron
from plumbum import local
schematron_doc = etree.parse(local.path('rules.sch'))
schematron = isoschematron.Schematron(schematron_doc)
xml_doc = etree.parse(local.path('test.xml'))
is_valid = schematron.validate(xml_doc)
assert not is_valid 

Что я получу: lxml.etree.XSLTParseError: xsltCompilePattern: не удалось скомпилировать «// ns1: bar»

Если я удаляю ns1 как из XML-файла, так и из файла Schematron, пример работает отлично - без сообщений об ошибках.

Должен быть прием для регистрации пространств имен в lxml Schematron, которыйЯ скучаю. Кто-нибудь делал это?

1 Ответ

4 голосов
/ 22 октября 2019

Как выясняется, существует особый способ регистрации пространств имен в Schematron. Он описан в стандарте Schematron ISO

. Требуется лишь небольшое изменение файла Schematron, добавив элемент "ns" следующим образом:

<?xml version='1.0' encoding='UTF-8'?>
<schema xmlns="http://purl.oclc.org/dsdl/schematron">
  <ns uri="http://foo" prefix="ns1"/>
  <pattern>
    <rule context="//ns1:bar">
      <assert test="number(.) = 2">
       bar must be 2
      </assert>
    </rule>
  </pattern>
</schema>

Я не буду снимать этот вопрос, поскольку примеров правил Schematron, использующих пространства имен, очень мало. Надеюсь, это кому-нибудь пригодится.

...