Подтвердить что ты не робот

Пространства имен XML и атрибуты

Я пытаюсь понять, как пространства имен работают в XML. Когда у меня есть элемент типа foo: bar, атрибуты часто не будут иметь пространства имен на них. Но иногда они будут. Является ли атрибут в пространстве имен элемента, даже если объявлено пространство имен по умолчанию? Оглядываясь на xsd для xhtml, кажется, что атрибуты являются частью схемы и должны находиться в пространстве имен для xhtml, но они никогда не представлены таким образом...

4b9b3361

Ответ 1

В большинстве случаев атрибуты не будут находиться в каком-либо пространстве имен. пространство имен говорит (внимание мое):

Объявление пространства имен по умолчанию применяется ко всем именам неповрежденных элементов в пределах области действия. Декларации пространства имен по умолчанию не применяются непосредственно к именам атрибутов; интерпретация неподписанных атрибутов определяется элементом, на котором они появляются.

Есть причина, по которой большинство словарей XML используют атрибуты, отличные от имен:
Когда ваши элементы имеют пространство имен, и эти элементы имеют атрибуты, тогда не может быть путаницы: атрибуты принадлежат вашему элементу, принадлежащему вашему пространству имен. Добавление префикса пространства имен к атрибутам просто сделает все более подробным.

Итак, почему существуют атрибуты с расширением имен?
Потому что некоторые словари полезны для работы с большей частью атрибутами и могут делать это, когда смешиваются с другими словарями. Наиболее известным примером является XLink.

Наконец, W3C XML Schema имеет слишком простой способ (<schema attributeFormDefault="qualified">) объявить ваши атрибуты как находящиеся в пространстве имен, заставляя их префикс их в ваших документах, даже если вы используете пространство имен по умолчанию.

Ответ 2

Примеры, иллюстрирующие использование обозначение Кларка, где префикс пространства имен заменяется URL-адресом пространства имен в фигурных скобках:

<bar xmlns:foo="http://www.foo.com/"
    foo:baz="baz"
    qux="qux"/>
<bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/"
    foo:baz="baz"
    qux="qux"/>
<foo:bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/"
    foo:baz="baz"
    qux="qux"/>

является

<{}bar
    {http://www.foo.com/}baz="baz"
    {}qux="qux"/>
<{http://www.foo.com/}bar
    {http://www.foo.com/}baz="baz"
    {}qux="qux"/>
<{http://www.foo.com/}bar
    {http://www.foo.com/}baz="baz"
    {}qux="qux"/>

Ответ 3

Там что-то связанное с этим атрибутом/пространством имен, которое заняло у меня некоторое время, чтобы понять сегодня, когда я работал над XSD. Я собираюсь поделиться этим опытом с вами, если у кого-нибудь случится одинаковые проблемы.

В документе схемы я работал над несколькими глобальными атрибутами, на которые ссылаются некоторые элементы. Чтобы упростить ситуацию, позвольте предположить, что XSD, о котором я говорю, касался Customer.

Позвольте назвать один из этих глобальных атрибутов 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-документ Customer следующим образом:

<?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, где парень по имени Стин Леманн предложил либо объявить атрибут локально, либо объявить его в группе атрибутов

", чтобы объявление атрибута сам уже не является глобальным"

Это последнее решение имеет "хакерский" вкус, поэтому я просто решил придерживаться первого решения и объявить все свои атрибуты локально.

Ответ 4

Читайте в 6.1 Область видимости пространства имен и 6.2 Пространство имен По умолчанию на w3c.

В принципе:

Область описания пространства имен, объявляющая префикс, продолжается от начала начального тега, в котором он отображается в конце соответствующего конечного тега

Однако текст здесь, похоже, не объясняет, означает ли это a foo: a или пространство имен по умолчанию в контексте. Я бы предположил, что это не относится к foo: a, а скорее к пространству имен по умолчанию a. Учитывая эту цитату как минимум:

Такое объявление пространства имен применяется ко всем именам элементов и атрибутов в пределах своей области, префикс которых соответствует указанному в объявлении.

Т.е. пространство имен "foo:" применяется только к элементам с префиксом foo: