Компонент, определяющий выражение XPath для схемы XML.
Полное описание, параметры и ограничения
ОпределенияXPathXS (XSXPathDefinition)
ОпределенияXPathXS (XSXPathDefinition)
Доступен, начиная с версии 8.1.
Свойства:
Аннотация (Annotation)
Компоненты (Components)
Контейнер (Container)
КорневойКонтейнер (RootContainer)
Схема (Schema)
ТипКомпоненты (ComponentType)
ЭлементDOM (DOMElement)
URIПространстваИмен (NamespaceURI)
Имя (Name)
XPath (XPath)
Вариант (Variety)
Методы:
КлонироватьКомпоненту (CloneComponent)
ОбновитьЭлементDOM (UpdateDOMElement)
Содержит (Contains)
Конструкторы:
По умолчанию
Описание:
Компонент, определяющий выражение XPath для схемы XML.
Доступность:
Сервер, толстый клиент, внешнее соединение.
См. также:
ОпределениеОграниченияИдентичностиXS, свойство Селектор
Использование в версии:
Доступен, начиная с версии 8.1.
Методическая информация
Практические примеры
Присоединить копию ключа к своей схеме и удалить её
Копируем CodeKey рекурсивно, присваиваем новое имя и добавляем только в свою коллекцию. После проверки XML-имени удаляем лишь созданную копию.
Где и как запускать
Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.
Подготовка
Запускайте каждый самостоятельный фрагмент на сервере учебной базы. Полная собственная XSD включена в начало кода. Дисковые файлы, сеть и рабочие документы не используются.
В схеме books содержит book и link. CodeKey описывает ключ book/@code, SupplierUnique — уникальность book/@supplier, CodeRef — ссылку link/@code на ключ книги.
Набор.Проверить проверяет саму схему, а не экземпляр XML с книгами. Эти уроки не выдают анализ схемы за проверку реального импортируемого документа.
XSD = "<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:g=""urn:guide:keys"" targetNamespace=""urn:guide:keys"" elementFormDefault=""qualified"">
| <xs:element name=""books""><xs:complexType><xs:sequence>
| <xs:element name=""book"" minOccurs=""0"" maxOccurs=""unbounded""><xs:complexType>
| <xs:attribute name=""code"" type=""xs:string"" use=""required""/>
| <xs:attribute name=""supplier"" type=""xs:string""/>
| </xs:complexType></xs:element>
| <xs:element name=""link"" minOccurs=""0"" maxOccurs=""unbounded""><xs:complexType>
| <xs:attribute name=""code"" type=""xs:string"" use=""required""/>
| </xs:complexType></xs:element>
| </xs:sequence></xs:complexType>
| <xs:key name=""CodeKey""><xs:selector xpath=""g:book""/><xs:field xpath=""@code""/></xs:key>
| <xs:unique name=""SupplierUnique""><xs:selector xpath=""g:book""/><xs:field xpath=""@supplier""/></xs:unique>
| <xs:keyref name=""CodeRef"" refer=""g:CodeKey""><xs:selector xpath=""g:link""/><xs:field xpath=""@code""/></xs:keyref>
| </xs:element>
|</xs:schema>";
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(XSD);
Попытка
ПостроительDOM = Новый ПостроительDOM;
DOM = ПостроительDOM.Прочитать(Чтение);
Чтение.Закрыть();
Исключение
Чтение.Закрыть();
ВызватьИсключение;
КонецПопытки;
Построитель = Новый ПостроительСхемXML;
Схема = Построитель.СоздатьСхемуXML(DOM.ЭлементДокумента);
Если Схема = Неопределено Тогда
ВызватьИсключение "Не построена собственная схема ключей";
КонецЕсли;
Набор = Новый НаборСхемXML;
Набор.Добавить(Схема);
Если Не Набор.Проверить() Тогда
ВызватьИсключение "Собственная схема ключей не прошла проверку";
КонецЕсли;
Корень = Схема.ОбъявленияЭлементов.Получить("books", "urn:guide:keys");
Если Корень = Неопределено Тогда
ВызватьИсключение "Не найден собственный корень books";
КонецЕсли;
Ограничения = Корень.ОграниченияИдентичности;
Если Ограничения.Количество() <> 3 Тогда
ВызватьИсключение "Ожидались три собственных ограничения";
КонецЕсли;
Ключ = Неопределено;
Уникальность = Неопределено;
Ссылка = Неопределено;
Для Каждого Ограничение Из Ограничения Цикл
Если ТипЗнч(Ограничение) <> Тип("ОпределениеОграниченияИдентичностиXS") Тогда
ВызватьИсключение "Ожидалось определение собственного ограничения";
КонецЕсли;
Если Ограничение.Имя = "CodeKey" Тогда
Ключ = Ограничение;
ИначеЕсли Ограничение.Имя = "SupplierUnique" Тогда
Уникальность = Ограничение;
ИначеЕсли Ограничение.Имя = "CodeRef" Тогда
Ссылка = Ограничение;
КонецЕсли;
КонецЦикла;
Если Ключ = Неопределено Или Уникальность = Неопределено Или Ссылка = Неопределено Тогда
ВызватьИсключение "Не найдены все три собственных определения";
КонецЕсли;
КопияКлюча = Ключ.КлонироватьКомпоненту(Истина);
Если ТипЗнч(КопияКлюча) <> Тип("ОпределениеОграниченияИдентичностиXS") Тогда
ВызватьИсключение "Не получена копия собственного ключа";
КонецЕсли;
КопияКлюча.Имя = "CodeKeyCopy";
Сообщить(Не Ключ.Содержит(КопияКлюча));
Ограничения.Добавить(КопияКлюча);
Сообщить(Ограничения.Количество() = 4);
Сообщить(КопияКлюча.Контейнер = Корень);
Сообщить(КопияКлюча.Селектор.XPath = "g:book");
Сообщить(КопияКлюча.Поля.Количество() = 1);
КопияКлюча.ОбновитьЭлементDOM();
Сообщить(КопияКлюча.ЭлементDOM.ПолучитьАтрибут("name") = "CodeKeyCopy");
Если Не Набор.Проверить() Тогда
ВызватьИсключение "Схема с собственной копией ключа не прошла проверку";
КонецЕсли;
Сообщить(Ключ.Имя = "CodeKey");
Ограничения.Удалить(КопияКлюча);
Сообщить(Ограничения.Количество() = 3);
Если Не Набор.Проверить() Тогда
ВызватьИсключение "Исходная схема после удаления своей копии не прошла проверку";
КонецЕсли;
Сообщить(Ссылка.СсылочныйКлюч.Имя = "CodeKey");Разбор по шагам
Рекурсивная копия содержит собственные селектор и поле. Её тип проверяется прежде чем менять имя.
Новое имя CodeKeyCopy избегает дублирования имени CodeKey в одной схеме.
Добавить действительно присоединяет копию к собственному объявлению books; после этого контейнер — Корень.
ОбновитьЭлементDOM отражает имя копии в DOM. Набор.Проверить проверяет структуру схемы после присоединения.
Удалить принимает ровно созданный объект копии. После удаления он не используется; оригинальный CodeKey и ссылка на него сохранены.
Как проверить результат
Девять сообщений Истина.
Ограничений сначала 3, с копией 4, после удаления снова 3.
Ожидаемый результат
Проверен полный жизненный цикл собственной копии ограничения.
На что обратить внимание
Не очищайте коллекцию чужой XSD: это удалит необходимые ограничения.
Проверяется схема, а не XML-файл импорта с реальными книгами.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Отличить XPath селектора от XPath поля ключа
Селектор g:book выбирает элементы, поле @code — атрибут каждой выбранной книги. Меняем только отдельную копию поля, оригинальное ограничение остаётся прежним.
Где и как запускать
Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.
Подготовка
Запускайте каждый самостоятельный фрагмент на сервере учебной базы. Полная собственная XSD включена в начало кода. Дисковые файлы, сеть и рабочие документы не используются.
В схеме books содержит book и link. CodeKey описывает ключ book/@code, SupplierUnique — уникальность book/@supplier, CodeRef — ссылку link/@code на ключ книги.
Набор.Проверить проверяет саму схему, а не экземпляр XML с книгами. Эти уроки не выдают анализ схемы за проверку реального импортируемого документа.
XSD = "<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:g=""urn:guide:keys"" targetNamespace=""urn:guide:keys"" elementFormDefault=""qualified"">
| <xs:element name=""books""><xs:complexType><xs:sequence>
| <xs:element name=""book"" minOccurs=""0"" maxOccurs=""unbounded""><xs:complexType>
| <xs:attribute name=""code"" type=""xs:string"" use=""required""/>
| <xs:attribute name=""supplier"" type=""xs:string""/>
| </xs:complexType></xs:element>
| <xs:element name=""link"" minOccurs=""0"" maxOccurs=""unbounded""><xs:complexType>
| <xs:attribute name=""code"" type=""xs:string"" use=""required""/>
| </xs:complexType></xs:element>
| </xs:sequence></xs:complexType>
| <xs:key name=""CodeKey""><xs:selector xpath=""g:book""/><xs:field xpath=""@code""/></xs:key>
| <xs:unique name=""SupplierUnique""><xs:selector xpath=""g:book""/><xs:field xpath=""@supplier""/></xs:unique>
| <xs:keyref name=""CodeRef"" refer=""g:CodeKey""><xs:selector xpath=""g:link""/><xs:field xpath=""@code""/></xs:keyref>
| </xs:element>
|</xs:schema>";
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(XSD);
Попытка
ПостроительDOM = Новый ПостроительDOM;
DOM = ПостроительDOM.Прочитать(Чтение);
Чтение.Закрыть();
Исключение
Чтение.Закрыть();
ВызватьИсключение;
КонецПопытки;
Построитель = Новый ПостроительСхемXML;
Схема = Построитель.СоздатьСхемуXML(DOM.ЭлементДокумента);
Если Схема = Неопределено Тогда
ВызватьИсключение "Не построена собственная схема ключей";
КонецЕсли;
Набор = Новый НаборСхемXML;
Набор.Добавить(Схема);
Если Не Набор.Проверить() Тогда
ВызватьИсключение "Собственная схема ключей не прошла проверку";
КонецЕсли;
Корень = Схема.ОбъявленияЭлементов.Получить("books", "urn:guide:keys");
Если Корень = Неопределено Тогда
ВызватьИсключение "Не найден собственный корень books";
КонецЕсли;
Ограничения = Корень.ОграниченияИдентичности;
Если Ограничения.Количество() <> 3 Тогда
ВызватьИсключение "Ожидались три собственных ограничения";
КонецЕсли;
Ключ = Неопределено;
Уникальность = Неопределено;
Ссылка = Неопределено;
Для Каждого Ограничение Из Ограничения Цикл
Если ТипЗнч(Ограничение) <> Тип("ОпределениеОграниченияИдентичностиXS") Тогда
ВызватьИсключение "Ожидалось определение собственного ограничения";
КонецЕсли;
Если Ограничение.Имя = "CodeKey" Тогда
Ключ = Ограничение;
ИначеЕсли Ограничение.Имя = "SupplierUnique" Тогда
Уникальность = Ограничение;
ИначеЕсли Ограничение.Имя = "CodeRef" Тогда
Ссылка = Ограничение;
КонецЕсли;
КонецЦикла;
Если Ключ = Неопределено Или Уникальность = Неопределено Или Ссылка = Неопределено Тогда
ВызватьИсключение "Не найдены все три собственных определения";
КонецЕсли;
Селектор = Ключ.Селектор;
Если ТипЗнч(Селектор) <> Тип("ОпределенияXPathXS") Тогда
ВызватьИсключение "Ожидался селектор собственного ключа";
КонецЕсли;
Если Ключ.Поля.Количество() <> 1 Тогда
ВызватьИсключение "Ожидалось одно поле собственного ключа";
КонецЕсли;
ПолеКода = Ключ.Поля.Получить(0);
Если ТипЗнч(ПолеКода) <> Тип("ОпределенияXPathXS") Тогда
ВызватьИсключение "Ожидалось поле XPath собственного ключа";
КонецЕсли;
Сообщить(Селектор.Вариант = ВариантXPathXS.Селектор);
Сообщить(ПолеКода.Вариант = ВариантXPathXS.Поле);
Сообщить(Селектор.XPath = "g:book");
Сообщить(ПолеКода.XPath = "@code");
Сообщить(ПолеКода.Контейнер = Ключ);
Сообщить(ПолеКода.КорневойКонтейнер <> Неопределено);
Сообщить(ПолеКода.Схема.ПространствоИмен = "urn:guide:keys");
Сообщить(ПолеКода.Аннотация = Неопределено);
Сообщить(ПолеКода.Компоненты.Количество() = 0);
Сообщить("Имя компонента XPath: " + ПолеКода.Имя);
Сообщить("URI компонента: " + ПолеКода.URIПространстваИмен);
Сообщить("Тип компонента XPath: " + Строка(ПолеКода.ТипКомпоненты));
ПолеКода.ОбновитьЭлементDOM();
Сообщить(ПолеКода.ЭлементDOM.ПолучитьАтрибут("xpath") = "@code");
КопияПоля = ПолеКода.КлонироватьКомпоненту(Истина);
Если ТипЗнч(КопияПоля) <> Тип("ОпределенияXPathXS") Тогда
ВызватьИсключение "Копия не является компонентом XPath";
КонецЕсли;
КопияПоля.XPath = "@supplier";
Сообщить(КопияПоля.XPath = "@supplier" И ПолеКода.XPath = "@code");
Сообщить(Не ПолеКода.Содержит(КопияПоля));
Сообщить(Не Ключ.Содержит(КопияПоля));Разбор по шагам
Ключ.Селектор и Ключ.Поля решают разные задачи: выбор объектов и извлечение значений ключа.
Доступ к полю 0 разрешён только после проверки количества. Оба компонента проверены на точный тип.
Префикс g связан с urn:guide:keys в исходной схеме. XPath book без префикса не подменяет g:book автоматически.
Свойства контейнера и схемы читаются у оригинального поля, присоединённого к собственному ключу.
КлонироватьКомпоненту создаёт отдельную копию. Изменение @supplier в ней не меняет @code оригинала и не добавляет копию в ключ автоматически.
Как проверить результат
Тринадцать сравнений Истина и три диагностические строки.
Оригинальный ключ использует @code после изменения независимой копии.
Ожидаемый результат
Селектор, поле и независимое клонирование проверены раздельно.
На что обратить внимание
Это ограниченный XPath для XSD, не произвольный язык запроса базы.
Изменение отсоединённого компонента не означает изменение действующей схемы.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.