Пространства имен и атрибуты XML - PullRequest
42 голосов
/ 03 сентября 2008

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

Ответы [ 4 ]

53 голосов
/ 06 сентября 2008

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

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

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

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

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

15 голосов
/ 04 сентября 2008

Примеры для иллюстрации с использованием нотации Clark , где префикс пространства имен заменяется 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"/>
9 голосов
/ 25 октября 2008

Есть что-то связанное с этой темой атрибутов / пространств имен, которое мне потребовалось некоторое время, чтобы понять сегодня, когда я работал над 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, где парень по имени Стин Леманн предложил либо объявить атрибут локально, либо объявить его в группе атрибутов

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

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

3 голосов
/ 03 сентября 2008

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

В основном:

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

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

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

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

...