Хобрук: Ваш путь к мастерству в программировании

xsd проверяет переменные xml в разных разделах одного и того же документа

Не уверен, что это возможно, но я хотел бы проверить с помощью xsd (версия 1.1), что переменные, используемые в документе xml, указаны в другом разделе того же документа.

Один раздел моего документа выглядит так:

<bf:Variables>
    <bf:Variable name="myVariable">
        ...
    </bf:Variable>
    <bf:Variable name="AnotherOne">
        ...
    </bf:Variable>
    <bf:Variable name="evenMore">
        ...
    </bf:Variable>
    ...
</bf:Variables>

Затем в том же документе у меня есть еще один раздел, который выглядит так:

<bf:Restrictions>
    <bf:Restriction variable="myVariable" operator="=">
        <bf:Value>True</bf:Value>
    </bf:Restriction>
    <bf:Restriction variable="AnotherOne" operator="=">
        <bf:Value>False</bf:Value>
    </bf:Restriction>
    <bf:Restriction variable="ThirdVariable" operator="=">
        <bf:Value>False</bf:Value>
    </bf:Restriction>
</bf:Restrictions>

Моя цель — проверить, что переменные, используемые в разделе ограничений, указаны в разделе переменных. В приведенном выше примере «Третья переменная» не должна пройти проверку xsd, поскольку ее нет в разделе «Переменные».


Ответы:


1

Это можно решить несколькими способами, некоторые лучше, чем другие


Решение с использованием assert, но не лучшее...

В XSD 1.1 это можно сделать с помощью файла <xs:assert>. В идеале утверждение должно быть размещено на ссылочном элементе <Restriction>, тогда будет очевидно, какой <Restriction> недействителен.

Однако, поскольку <xs:assert> не может получить доступ к значениям выше в дереве, <xs:assert> должен быть достаточно высоким, чтобы <Restriction> и <Variable> находились в пределах его области действия (дочерние элементы). Это было бы хорошо, но теперь вам нужно написать общее правило, которое, если оно не сработает, не даст много обратной связи — оно просто сообщит вам, что один или несколько из <Restriction> недействительны.

Вот очень быстрый образец для демонстрации.

Визуальное представление схемы, созданное с помощью Liquid XML Studio

<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.0 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="base">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="var" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
                <xs:element name="Usage" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
            <xs:assert test="count(Usage[not(./text() = ../var/text())]) = 0" />
        </xs:complexType>
    </xs:element>
</xs:schema>

Пример XML

<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid XML 2016 Developer Bundle Edition 14.1.4.6649 (https://www.liquid-technologies.com) -->
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Schema.xsd">
    <var>var1</var>
    <var>var2</var>
    <var>var4</var>
    <Usage>var1</Usage>
    <Usage>var2</Usage>
    <Usage>var3</Usage><!-- INVALID -->
</base>

Сообщение об ошибке (через Saxon)

(10:7) Критическое cvc-утверждение: оценка утверждения ('count(Usage[not(./text() = ../var/text())]) = 0') для элемента 'base' по типу схемы' #AnonType_base' не удалось.





Лучшее решение с использованием Key/KeyRef

Это дружественно к XSD 1.0 и работает очень хорошо. Он сообщает вам, есть ли у вас повторяющиеся имена переменных, а также если ссылка на имя переменной недействительна, указывая вам на реальную проблему.

Визуальное представление ключевой схемы keyref из Liquid XML Studio

<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.0 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="base">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Variables">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Variable" minOccurs="0" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:simpleContent>
                                        <xs:extension base="xs:string">
                                            <xs:attribute name="name" type="xs:string" />
                                        </xs:extension>
                                    </xs:simpleContent>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="Restrictions">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Restriction" minOccurs="0" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:simpleContent>
                                        <xs:extension base="xs:string">
                                            <xs:attribute name="variable" type="xs:string" />
                                        </xs:extension>
                                    </xs:simpleContent>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="VarDef">
            <xs:selector xpath="./Variables/Variable" />
            <xs:field xpath="@name" />
        </xs:key>
        <xs:keyref name="VarRef" refer="VarDef">
            <xs:selector xpath="./Restrictions/Restriction" />
            <xs:field xpath="@variable" />
        </xs:keyref>
    </xs:element>
</xs:schema>

Пример XML

<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.0 (https://www.liquid-technologies.com) -->
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SchemaKeyRef.xsd">
    <Variables>
        <Variable name="var1"></Variable>
        <Variable name="var2"></Variable>
        <Variable name="var3"></Variable>
    </Variables>
    <Restrictions>
        <Restriction variable="var1">string</Restriction>
        <Restriction variable="var2">string</Restriction>
        <Restriction variable="UNKNOWN">string</Restriction>
    </Restrictions>
</base>

Теперь генерируемая ошибка стала более конкретной, что значительно упрощает отладку проблемы.

Ошибка из .Net (номер строки является неверным ограничением)

(12:10) Ошибка Последовательность клавиш «НЕИЗВЕСТНО» в «VarDef» Keyref не может ссылаться на какой-либо ключ.

Ошибка от Saxon (номер строки является содержащей элементной базой)

(14:7) Критическое cvc-identity-constraint.4.3: Ключ «VarRef» со значением «UNKNOWN» не найден для ограничения идентичности элемента «base».

06.09.2016
Новые материалы

Управление DOM для чайников вроде меня
Одной из первых вещей, которую мы рассмотрели, когда начали изучать Javascript во Flatiron, была модель DOM. Кто он? Чем он занимается? Он больше машина, чем человек? Ну да довольно много. ДОМ..

Что такое структура данных?
Структура данных хранит и извлекает данные. Все, что обеспечивает эти две функции, является структурой данных . Период. Вы можете пропустить оставшуюся часть статьи, если ответ..

мои январские чтения по программированию
Эрик Эллиот Программирование приложения JavaScript Эл Свейгарт «Автоматизируйте скучные вещи с помощью Python» Прогрессивное веб-приложение Google..

Создание ассоциаций секвелизации с помощью инструмента командной строки Sequelize
Sequelize - популярный, простой в использовании инструмент объектно-реляционного сопоставления (ORM) JavaScript, который работает с базами данных SQL. Довольно просто начать новый проект с..

Искусственный интеллект в юридической отрасли - пример прогнозирования судебных решений с помощью глубокого обучения
На протяжении всей истории люди полагались на суды, присяжных, королей и королев в отправлении правосудия. Сегодня способность судов обеспечивать справедливое и быстрое правосудие для своих..

Введение в машинное обучение для обнаружения аномалий (часть 1)
Тщательно созданный, тщательно спроектированный ресурс для специалистов по данным. Часть 1 Главы 03 из Руководства по машинному обучению для обнаружения аномалий Внимание! Прежде чем вы..

Начало работы с Pulumi в Digital Ocean
Цифровой океан (ДО) — отличная альтернатива многим другим поставщикам облачных услуг. DO предоставляет простой и понятный пользовательский интерфейс, упрощающий управление инфраструктурой и..