Есть что-то связанное с этой темой атрибутов / пространств имен, которое мне потребовалось некоторое время, чтобы понять сегодня, когда я работал над XSD.
Я поделюсь с вами этим опытом на случай, если у кого-нибудь возникнут те же проблемы.
В документе схемы, над которым я работал, было несколько глобальных атрибутов, на которые ссылаются некоторые элементы. Для упрощения здесь давайте предположим, что этот XSD, о котором я говорю, был о клиенте .
Давайте назовем один из этих глобальных атрибутов Id . И корневой элемент с его помощью Клиент
Моя XSD-декларация выглядела так:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://schemas.mycompany.com/Customer/V1"
targetNamespace="http://schemas.mycompany.com/Customer/V1"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
My Id объявление атрибута выглядело так:
<xs:attribute name="Id" type="xs:positiveInteger"/>
И мой Клиент элемент использовал атрибут следующим образом:
<xs:element name="Customer">
<xs:complexType>
<xs:attribute ref="Id" use="required"/>
<!-- some elements here -->
</xs:complexType>
</xs:element>
Теперь, допустим, я хотел объявить Клиент XML-документ, например:
<?xml version="1.0" encoding="utf-8"?>
<Customer Id="1" xmlns="http://schemas.mycompany.com/Customer/V1">
<!-- ... other elements here -->
</Customer>
Я обнаружил, что не могу: когда атрибут объявлен глобально, он не находится в том же пространстве имен, что и элемент, который на него ссылается.
Я выяснил, что единственное решение с таким определением XSD состоит в том, чтобы объявить пространство имен дважды: один раз без префикса, чтобы сделать его пространством имен по умолчанию для элементов, и один раз с префиксом, чтобы использовать его с атрибутов. Вот как это выглядело бы:
<?xml version="1.0" encoding="utf-8"?>
<Customer cus:Id="1" xmlns="http://schemas.mycompany.com/Customer/V1"
xmlns:cus="http://schemas.mycompany.com/Customer/V1">
<!-- ... other elements here -->
</Customer>
Это настолько непрактично, что я просто решил избавиться от всех глобальных атрибутов и объявить их локально. Что в случае с примером, который я привел здесь, выглядело бы так:
<xs:element name="Customer">
<xs:complexType>
<xs:attribute name="Id" type="xs:positiveInteger" use="required"/>
<!-- some elements here -->
</xs:complexType>
</xs:element>
Мне было трудно найти некоторые ссылки на то, о чем я говорю, здесь, в сети. В итоге я нашел этот пост на форуме Stylus XSD, где парень по имени Стин Леманн предложил либо объявить атрибут локально, либо объявить его в группе атрибутов
"так, чтобы объявление атрибута
сам по себе больше не глобален "
Это последнее решение имеет "хакерский" вкус, поэтому я просто решил придерживаться первого решения и объявить все свои атрибуты локально.