Как проверить, что одна схема XSD является подмножеством другой схемы XSD?
Как я могу проверить, что одна схема XSD является подмножеством другой схемы XSD?
Мы создаем приложение системной системы, используя набор схем XSD "blueprint" (который определяет все возможные входы или выходы, доступные субкомпоненту). Многие субкомпоненты внедряются, и эти субкомпоненты передают данные между собой, используя файлы XML. Каждый подкомпонент создает подмножество соответствующей схемы XSD проекта (чтобы указать, какой из возможных входов или выходов он выбрал для реализации). Любой XML-файл данных, который проверяется по подмножеству XSD-схемы, должен также проверяться по схеме XSD-схемы, но обратное неверно (поскольку подмножество-XSD-схема может содержать не все "необязательные" или "выборочные" элементы XML из схемы XSD-схемы, и он может выбрать дальнейшее ограничение допустимых значений данных для существующего тега XML). Система проверит все входные данные XML для подкомпонента в соответствии с XSD-схемой подмножества этого подкомпонента (чтобы пометить любые неправильные входные данные и изолировать источник проблем, связанных с данными).
Во время тестирования мы намереваемся проверить, что схема XSD каждого подкомпонента действительно является подмножеством связанной схемы XSD, но у нас нет автоматизированных средств для выполнения этой проверки. Эти XSD-схемы довольно большие и уродливые, поэтому их нужно проводить вручную. Было бы неплохо иметь своего рода команду "validate XSD file 1 против XSD file 2", аналогично тому, как Java может выполнять проверку XML-файла по схеме XSD. Мы хотим подтвердить, что схема XSD каждого подкомпонента не допускает никаких комбинаций ввода / вывода XML, которые нарушали бы схему XSD проекта. С этой возможностью схемы-схемы было бы также очень полезно проверить, подходит ли выходной XML из подкомпонента A в качестве входного для подкомпонента B (мы можем легко проверить один выходной XML по схеме XSD, но мы хотим подтвердить, что все возможные выходные XML-данные из подкомпонента A будут проверены на соответствие схеме XSD подкомпонента B).
Полезная информация: Это приложение представляет собой набор приложений Java 6, реализованных в виде пакетов OSGi и скомпилированных / выполненных с использованием Maven 2.2.1. Нет никаких требований для использования какой-либо конкретной среды разработки. Система тестируется в среде Microsoft Windows XP, но планируется использовать эту систему и в других средах (поэтому было бы предпочтительным кроссплатформенное решение).
4 ответа
Самый простой способ обеспечить требуемые отношения - это получить типы схем подмножества путем ограничения по типам схемы проекта. Звучит так, будто эта лодка уже плыла.
Как и другие здесь, я не знаю о каких-либо инструментах, которые делают это из коробки (хотя, если Petru Gardea скажет, что QT Assistant может, стоит продолжить).
Одна сложность заключается в том, что существует два различных способа просмотра отношения подмножество / надмножество, которое вы хотите проверить: (1) каждый документ (или элемент), принятый как действительный по схеме 1, также принимается как действительный по схеме 2 (без ссылки на тип выполненные присваивания) или (2) типизированные документы, созданные путем проверки (в том, что спецификация называет инфо-набором после проверки схемы) для схем 1 и 2, находятся в соответствующем отношении друг к другу: если элемент или атрибут действителен в дерево 1, оно действительно в дереве 2; тип, назначенный ему в дереве 1, является ограничением типа, назначенного ему в дереве 2; и т. д. Если схемы 1 и 2 были разработаны независимо, шансы на то, что их типы связаны с производными, невелики, поэтому, я думаю, у вас есть первый подход к вопросу.
Проблема, безусловно, разрешима в любой форме. Для любой схемы (я использую термин осторожно) по определению существует конечное число типов и конечное число имен элементов; Отсюда следует, что существует конечное число (возможно, большое) пар имя / тип элемента.
Алгоритм может пойти примерно так.
Начните с ожидаемого корневого элемента. (Если имеется несколько возможных корневых элементов, то в общем случае вам нужно будет выполнить эту проверку для каждого из них.) Если ожидаемый корневой элемент - E, с типом T1 в схеме 1 и типом T2 в схеме 2, тогда поместите задачу "Сравните типы T1 и T2" в очередь открытых задач. Список уже выполненных задач будет пустым.
Для сравнения двух сложных типов T1 и T2:
Проверьте наборы атрибутов, объявленных для T1 и T2, на предмет подмножества / надмножества между их именами. Убедитесь, что атрибут не требуется в предполагаемом подмножестве, отсутствует или не является обязательным в предназначенном подмножестве.
Каждому атрибуту A, объявленному как для T1, так и для T2, будет присвоен тип (назовите их ST1 и ST2). Если ST1 = ST2, ничего не делать; в противном случае добавьте задачу "Сравнение простых типов ST1 и ST2" в очередь открытых задач, если она не включена в список выполненных сравнений.
Теперь проверьте последовательности дочерних элементов, которые возможны в T1 и T2 - как предполагает 13ren в комментарии, это можно отследить, поскольку модели содержимого - это, по сути, регулярные выражения, которые используют набор имен элементов в качестве своего алфавита; поэтому определяемые ими языки являются регулярными, и отношение подмножество / надмножество разрешается для обычных языков.
Каждому возможному дочернему элементу C назначаются как объявление элемента, так и определение типа родительскими типами T1 и T2. Давайте назовем их ED1, ED2, CT1 и CT2. Каждый дочерний элемент с одинаковым именем будет иметь один и тот же тип, но разные дочерние элементы могут соответствовать разным объявлениям элементов. Таким образом, для любого возможного имени будет только одна пара типов CT1 и CT2, но может быть несколько пар ED1 и ED2 (и анализ должен быть осторожным, чтобы убедиться, что они сопоставлены правильно; это может быть трудно автоматизировать).
Если CT1 = CT2, ничего не делать, в противном случае поместите "Сравнить типы CT1 и CT2" в открытую очередь задач, если сравнение не было выполнено.
Если ED1 и ED2 структурно идентичны, ничего не делать; в противном случае поставьте задачу сравнения их в очередь задач (если это еще не сделано).
Чтобы сравнить два простых типа ST1 и ST2, сравните либо их лексические пространства (если вы хотите первое определение отношения подмножество / надмножество в схемах), либо их пространства значений (если вы хотите второе). Если ST1 и ST2 оба являются ограничениями одного и того же примитивного типа, вы можете легко сравнить набор эффективных ограничений на них на основе фасетов. Фасет шаблона может усложнить ситуацию, но поскольку он определяет набор регулярных выражений, отношение подмножество / надмножество для него разрешимо.
Чтобы сравнить объявления двух элементов, необходимо сравнить каждое из свойств для объявления элемента и проверить наличие требуемого отношения подмножество / надмножество.
Как видите, он достаточно сложен и утомителен, что вы действительно хотите автоматизировать этот анализ, а также достаточно сложен, чтобы легко понять, почему он не широко предлагается как готовая функция. Но было бы интересно написать код.
Инструменты, которые проверяют XML по схеме, уже знают, как это сделать, потому что в случае <xs:complexContent><xs:restriction>
требуется, чтобы вновь определенный тип был подмножеством ограниченного типа.
Если вы хотите использовать эту функцию, вы можете попросить дочерние схемы определять сложные типы, которые ограничивают типы в вашей схеме.
Однако, если дочерние схемы создаются без учета этого, это, возможно, все еще может быть достигнуто путем изменения дочерних схем в соответствии с шаблоном ниже, а затем отправки их через процессор схем для проверки.
Пример схемы проекта, blueprintschema.xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="rootType"/>
<xs:complexType name="rootType">
<xs:sequence>
<xs:element name="child1" minOccurs="0"/>
<xs:element name="child2" minOccurs="0"/>
<xs:element name="child3" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Пример дочерней схемы, которая является подмножеством схемы проекта:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="rootType"/>
<xs:complexType name="rootType">
<xs:sequence>
<xs:element name="child2"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Пример дочерней схемы после преобразования в переопределенную конструкцию:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:redefine schemaLocation="blueprintschema.xsd">
<xs:complexType name="rootType">
<xs:complexContent>
<xs:restriction base="rootType">
<xs:sequence>
<xs:element name="child2"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
<xs:element name="root" type="rootType"/>
</xs:schema>
Затем обработчик схемы скажет вам, является ли переопределенный "rootType" на самом деле подмножеством исходного проекта "rootType"
Поскольку схема - это всего лишь XML, преобразование можно выполнить с помощью обычных инструментов обработки XML.
Спасибо тебе, @13ren, за твой "гудок":)
Это длинный комментарий, а не ответ. Я начну с моего более раннего обмена с 13ren, more precise, it provides to a user all that is needed to define such an analysis model.
Я имел в виду, что в QTAssistant ( этот) у нас есть функция сравнения XSD; будучи осведомленным о XSD, он уже делает многое из того, что не может сделать текстовый или XML-разностный инструмент (например, ему все равно, сколько XSD-файлов, их разметка изменяется между версиями и т. д.) для предоставленного пользовательского интерфейса, механизм сравнения работает против исходной модели, в отличие от модели PSVI. Мы могли бы настроить его для использования PSVI, поскольку последний на шаг ближе к тому, что вам действительно нужно. Мы могли бы также включить возможность иметь пользовательский набор правил для увеличения сравнения между "base" и "revision", другими словами, чтобы позволить пользователю переопределить оператор "=", который мы используем в настоящее время.
Я признаю, что у нас нет ничего из коробки, позволяющей переопределить сравнение фасетов xsd:pattern; ни для чего-то, что человеку легко узнать, например, xsd:positiveInteger
против xsd:integer + xsd:minInclusive=1
, Или сравнивая xsd:all
к xsd:choice
или же xsd:sequence
; и к тому же мы не разбираем селекторы и поля для ограничений XSD, с которыми, как и с регулярными выражениями, было бы нелегко иметь дело.
Предполагая, что цель состоит в том, чтобы найти как можно больше "расхождений", а не исключать их полностью, QTAssistant имеет еще три полезные функции:
- для данного корневого элемента он создает полный список простых XPath. Это может быть применено как быстрый способ обнаружить "мошеннические" данные. Этот метод сравнения не учитывает структурные закономерности, т. Е. Если XPath1 и XPath2 обозначают двух братьев и сестер в экземпляре XML, то XPath1 должен предшествовать XPath2) и т. Д.
- Он поставляется со встроенным анализатором Query XSD. SQL может использоваться для запроса метамодели XSD набора, чтобы "определить" вещи, которые указывают на вещи, которые инструмент сравнения может быть разработан, чтобы игнорировать (для осуществимости), и, следовательно, потребует отчета для принятия решения человеком.
- XSD Refactoring (XSR). Это единственный двигатель в отрасли (о котором я знаю, по крайней мере), созданный с нуля с учетом рефакторинга и анализа XSD. Я думаю, что если вы можете исключить xsi:type и, в идеале, использование групп замещения (об этом мне еще нужно подумать), мы могли бы сделать доступным то, что мы называем "преобразованием канонизации" - причудливое слово для преобразуйте набор схем в стиль дизайна Russian Doll, полагаясь на модель PSVI. Здесь может быть много вещей: использование атрибута id, свертывание лишних последовательностей, замена единственного параметра xsd: выборы и т. Д., Поэтому у нас он находится в разработке, но еще не опубликован.
Еще одна вещь, которую мы должны были предусмотреть в нашем сравнении (и вы, возможно, захотите рассмотреть), была связана с эквивалентностью не только XSD/XML, но и артефактов, сгенерированных из XSD (например, классов Java через JAXB); в довершение всего, шаблоны расширяемости, те, которые используют подстановочные знаки (xsd:any и anyAttribute).
Мы (QTAssistant) в настоящее время заинтересованы работать с вами, выполняя некоторые более конкретные требования (нам нужно начать с обмена репрезентативными XSD, NDA, я бы предположил и т. Д.), Вне диапазона, чтобы посмотреть, действительно ли мы можем это сделать. Работа. Если вы хотите продолжить, не стесняйтесь связаться со мной через адрес поддержки веб-сайта, связанного с моим профилем SO.
Поскольку в настоящее время нет доступного решения для проверки / проверки схемы относительно другой схемы, похоже, что мы должны использовать обходные пути. Ниже моя попытка.
Решение проблемы:
Определите, все ли типы данных, определенные в схеме подмножества, существуют и находятся в пределах (менее строгих) границ того, что определено в схеме "плана".
Возможное решение:
- Первая (очевидная) информация заключается в том, что Schema позволяет нам создавать экземпляры XML (что это вообще значит?! см. 2.).
- Другая часть (не столь очевидной) информации, которой мы располагаем, заключается в том, что сама схема XML может быть "экземпляром подмножества" - под этим я подразумеваю следующее: если вам придется провести обратный инжиниринг схемы из вашего экземпляра XML, то у вас есть схема подмножества (это утверждение не всегда верно, если у вас нет "списков" или элементов выбора или других "границ", тогда обратная схема сконструированного подмножества будет точно соответствовать схеме "чертежа").
Итак, используя эти знания, мы можем построить решение:
Создайте все возможные экземпляры XML схемы подмножества (выполнение этого шага программно может быть сложной задачей) и проверьте эти экземпляры XML по схеме "blueprint".
Но откуда вы знаете, что схема подмножества является подмножеством схемы "плана"? Итак, поскольку вы создали все возможные экземпляры XML схемы подмножества, она охватила все типы данных, присутствующие в схеме подмножества. И проверяя эти экземпляры XML на соответствие схеме "blueprint", по сути, проверяется, существуют ли типы данных и все ли находится в границах того, что определено в схеме "blueprint". Следовательно, выявление того, что ваша схема подмножества действительно является подмножеством схемы "плана".
Я знаю, что это не идеальное решение, но надеюсь, что это поможет, поскольку не существует простого способа сделать то, что вы просите.