Зачем нам нужен targetNamespace? - PullRequest
50 голосов
/ 24 марта 2012

Я хотел бы понять назначение targetNamespace, которое используется как в XML-схеме, так и в WSDL. На самом деле, для простоты, давайте ограничим этот вопрос схемой XML.

Мне кажется, я полностью понимаю понятие (простых) пространств имен XML. По соглашению мы используем URI / URL, но мы можем использовать любую строку, которую мы затем назначаем префиксу для повторного использования узлами и атрибутами XML, или просто используем в качестве пространства имен по умолчанию для рассматриваемой области. Пока все хорошо?

Теперь вводит XML-схему. По какой-то причине изобретатели XML-схемы сочли, что понятия простых пространств имен недостаточно, и им пришлось ввести targetNamespace. Мой вопрос: какое существенное преимущество приносит targetNamespace, которое не может быть обеспечено обычным пространством имен XML? Если документ XML ссылается на документ xsd, либо с помощью schemaLocation, либо с помощью оператора импорта, в любом случае я даю путь к действительному документу xsd, на который ссылаются. Это то, что однозначно определяет схему, к которой я хочу обратиться. Если, кроме того, я хочу привязать эту схему к определенному пространству имен в моем документе, на который есть ссылки, почему я должен быть обязан воспроизвести точное целевое пространство имен, уже определенное в схеме XML, на которую я ссылаюсь? Почему я не могу просто переопределить это пространство имен, как бы мне ни хотелось в документе XML, в котором это пространство имен будет использоваться для ссылки на тот конкретный документ схемы XML, на который я хочу сослаться?

Обновление:

Чтобы привести пример, если у меня есть следующее в экземпляре документа XML:

<p:Person
   xmlns:p="http://contoso.com/People"
   xmlns:v="http://contoso.com/Vehicles"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation=
    "http://contoso.com/schemas/Vehicles
     http://contoso.com/schemas/vehicles.xsd
     http://contoso.com/schemas/People
     http://contoso.com/schemas/people.xsd">
   <name>John</name>
   <age>28</age>
   <height>59</height>
   <v:Vehicle>
      <color>Red</color>
      <wheels>4</wheels>
      <seats>2</seats>
   </v:Vehicle>
</p:Person>

Почему, например, Схема people.xsd должна определить targetNamespace, который имеет вид "http://contoso.com/schemas/People"?. Зачем нам вообще нужно определение targetNamespace в документе xsd? Мне кажется, все, что вам нужно получить от части пространства имен в schemaLocation, уже содержится в документ экземпляра XML. В чем заключается преимущество принудительного существования объекта targetNamespace с равным значением в документе xsd?

Дополнительный вопрос к ответу Павла:

Можете ли вы привести конкретный пример, когда такие "столкновения" между именами элементов xsd становятся очевидными и это объясняет необходимость в targetNamespace?


Хорошо, вот попытка ответить на мой собственный вопрос. Дайте мне знать, если это кажется вам последовательным. Мне помогли примеры на странице, на которую ссылается Пол.

Если мы возьмем пример экземпляра XML из исходного вопроса выше, у нас есть две ссылки на определение элемента транспортного средства. Один является явным и видимым в самом документе экземпляра XML, но мы также должны представить, что XML-схема person.xsd снова ссылается на то же определение транспортного средства, что и на разрешенный дочерний элемент person. Если бы мы использовали обычные пространства имен, где каждому документу было разрешено определять свое собственное пространство имен для транспортного средства, как бы мы узнали, что экземпляр XML ссылается на то же определение схемы XML для транспортного средства, что и person.xsd? Единственный способ заключается в применении концепции пространства имен, которая является более строгой, чем первоначальная простая, и которая должна быть написана одинаково для нескольких документов.

Если бы я не писал это на планшете, я бы представил пример кода, но здесь я просто попытаюсь описать пример, который я имею в виду.

Представьте, что у нас есть два разных определения XML-схемы для элемента транспортного средства.location1 / Vehicles.xsd будет содержать определение, которое подтверждает пример из вопроса этого поста (содержит дочерние элементы color, wheel и seat), тогда как location2 / Vehicles.xsd будет содержать совершенно другое определение для элемента Vehicle (скажем,, с дочерними элементами год, модель и объем).Теперь, если экземпляр XML-документа ссылается на схему location1, как в случае с приведенным выше примером, но person.xsd говорит, что элемент person может содержать дочерний элемент транспортного средства типа, определенного в схеме location2, тогда без понятияобъекта targetNamespace, экземпляр XML будет проверяться, даже если у него явно нет нужного типа транспортного средства в качестве дочернего элемента его элемента person.

Целевые пространства имен помогают нам убедиться, что если два разных документассылаются на одну и ту же третью XML-схему, что они на самом деле ссылаются на одну и ту же схему, а не просто на схему, которая содержит элементы, которые похожи, но не идентичны друг другу ...

Имеет ли это какой-то смысл

Ответы [ 4 ]

17 голосов
/ 28 марта 2012

Вы, кажется, на правильном пути.Здесь я сделаю несколько замечаний, которые могут помочь.

  • В экземпляре документа вы используете пространства имен XML для идентификации пространства имен, в котором находится элемент или атрибут.
  • В пределахСхема документа, вы объявляете элементы и атрибуты, которые будут появляться в экземплярах.В каком пространстве имен они объявлены?Это то, для чего предназначен targetNamespace.
  • Расположение документа схемы и пространство имен - это не одно и то же.Весьма распространено иметь несколько документов .xsd с одним и тем же targetNamespace.(Они могут включать или не включать друг друга, но обычно будут включать друг друга.)
  • Документы экземпляра не всегда имеют элемент xsi: schemaLocation, чтобы сообщать анализаторам, где найти схемы.Различные методы могут использоваться, чтобы сообщить парсеру, где найти соответствующие документы схемы.XSD может находиться на локальном диске или по какому-либо веб-адресу, и это не должно влиять на пространство имен элементов в нем.
    • xsi: schemaLocation - это подсказка.Синтаксические анализаторы могут найти схему для данного пространства имен в другом месте, что подразумевает, что они должны знать, для какого пространства имен используется схема.
    • Инструменты, такие как инструменты привязки данных, прекомпилируют схемы и генерируют код, который распознает действительные документы.,Они должны быть в состоянии знать пространства имен объявленных элементов.

Я думаю, вы предполагали, что экземпляр документа может указывать пространство имен элементов и атрибутов, объявленных внекоторый документ схемы, используя xsi: schemaLocation.Это не работаетВо-первых, синтаксический анализатор может найти другие документы схемы, кроме перечисленных, и ему необходимо знать, для какого пространства имен они предназначены.С другой стороны, это сделало бы рассуждение о схемах трудным или невозможным: вы не смогли бы взглянуть на схему и узнать пространства имен, к которым принадлежит все, потому что это решение будет отложено до тех пор, пока экземпляр не будет написан.

14 голосов
/ 24 марта 2012

Q: "По соглашению мы используем URI / URL, но мы можем использовать любую строку, которая затем мы назначаем префикс для повторного использования узлами и атрибутами XML, или используйте просто как пространство имен по умолчанию для рассматриваемой области. "

A: Да, точно.

В: «По какой-то причине изобретатели XML Schema почувствовали понятие простых пространств имен было недостаточно, и они должны были представить целевое пространство. "

A: http://www.liquid -technologies.com / Учебники / XmlSchemas / XsdTutorial_04.aspx

Разбиение схем на несколько файлов может иметь несколько преимуществ. Вы можете создавать определения многократного использования, которые можно использовать в нескольких проектах. Они облегчают чтение и верстку определений, поскольку разбивают схему на более мелкие единицы, которые проще в управлении.

...

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

Пояснение:

  • Основной целью XML-схем является объявление "словарей".

  • Эти словари можно идентифицировать по пространству имен, указанному в атрибуте targetNamespace.

  • Схема (документ XML) может иметь «пространство имен». «Словарь», описанный в документе, может иметь «targetNamespace».

  • Так же, как схемы XML обеспечивают более высокий уровень абстракции, чем DTD SGML (первоначальные разработчики XML считали DTD достаточными), схема XML "targetNamespaces" обеспечивает уровень абстракции над "простыми пространствами имен".

Надеюсь, это поможет

11 голосов
/ 04 марта 2015

Я думаю, что это помогает одновременно просматривать и документ экземпляра, и документ схемы, чтобы понять, что делает targetNamespace.Учтите это (на основе вашего экземпляра документа):

<p:Person
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://localhost:8080/scribble/xml/Person"
        xmlns:v="http://localhost:8080/scribble/xml/Vehicle"
        xsi:schemaLocation="
            http://localhost:8080/scribble/xml/Person
            http://localhost:8080/scribble/xml/person.xsd">
    <name>John</name>
    <age>28</age>
    <height>59</height>
    <v:Vehicle>
        <color>Red</color>
        <wheels>4</wheels>
        <seats>2</seats>
    </v:Vehicle>
</p:Person>

Пространство имен по умолчанию не указано для документа, но p: * и v: * имеют псевдонимы для определенных NS URI.Теперь взглянем на сам документ схемы:

<?xml version="1.0" encoding="UTF-8"?>
<schema
    xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://localhost:8080/scribble/xml/Person"
    elementFormDefault="qualified"
    xmlns:v="http://localhost:8080/scribble/xml/Vehicle">

    <import
        namespace="http://localhost:8080/scribble/xml/Vehicle"
        schemaLocation="http://localhost:8080/scribble/xml/v.xsd"/>

    <element name="Person">
        <complexType>
            <sequence>
                <element name="name" form="unqualified" type="NCName"/>
                <element name="age" form="unqualified" type="integer"/>
                <element name="height" form="unqualified" type="integer"/>
                <element ref="v:Vehicle"/>
            </sequence>
        </complexType>
    </element>

</schema>

и

<?xml version="1.0" encoding="UTF-8"?>
<schema
    xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://localhost:8080/scribble/xml/Vehicle"
    elementFormDefault="qualified">

    <element name="Vehicle">
        <complexType>
            <sequence>
                <element name="color" form="unqualified" type="NCName"/>
                <element name="wheels" form="unqualified" type="integer"/>
                <element name="seats" form="unqualified" type="integer"/>
            </sequence>
        </complexType>
    </element>
</schema>

Если вы посмотрите на атрибуты тегов, пространство имен по умолчанию будет "http://www.w3.org/2001/XMLSchema"для обоих документов схемы ... но targetNamespace - это то, которое используется в качестве псевдонима пространства имен в документе экземпляра.

targetNamespace - это ожидаемое пространство имен экземпляров независимо от пространства имен документов схемы и любого другого пространства именуказанный в экземпляре документа.

Мне кажется, что это полезно думать о том, чтобы устроить вечеринку, на которой у вас есть список гостей и гости, носящие теги имен. Думайте о пространстве имен targetNamespace в документах схемы подобно именамв списке гостей. xmlns, с псевдонимом или нет, в документах экземпляра похожи на теги имен на гостях. Пока у вас есть список гостей (который чудесным образом включает в себя фотокопию их выданного государством ID), всякий раз, когда вывстретив кого-то, вы можете подтвердить его личность. Если вы встретите кого-то с именной биркойкоторый не соответствует прикрепленным параметрам, вы можете испугаться (то есть выбросить ошибку).

Со схемой / экземплярами у вас есть:

Схемы:

targetNamespace="http://localhost:8080/scribble/xml/Person"
targetNamespace="http://localhost:8080/scribble/xml/Vehicle"

Экземпляр:

xmlns:p="http://localhost:8080/scribble/xml/Person"
xmlns:v="http://localhost:8080/scribble/xml/Vehicle"

Или ... любой гость по кличке "v", с которым вы встречаетесь где-либо в группе (за исключением особых правил, которые говорят иначе), на любом этаже дома или на заднем дворе или впул, лучше сопоставьте описание для гостя в списке гостей с именем http://localhost:8080/scribble/xml/Vehicle. или они являются злоумышленниками.

В этих специальных правилах может быть что-то вроде:re рядом с P, или P может зависать только при наличии V.В этом случае P должен зависнуть, когда есть V, но V может пойти куда угодно, без присутствия A.

Таким образом, схема может быть невероятно гибкой, определяя практически любую желаемую структуру данных ивозможность отслеживать, что происходит, просто сопоставляя пространства имен (по умолчанию или с префиксами) любого данного элемента обратно в TNS и связанную схему.

4 голосов
/ 24 марта 2012

Мне не совсем понятно, о чем вы спрашиваете. Очевидно, что схема может содержать определения компонентов во многих различных пространствах имен, и должен быть какой-то способ сказать «Это объявление элемента E в пространстве имен N». Разработчики XSD решили спроектировать язык так, чтобы все объявления в одном документе схемы принадлежали одному и тому же пространству имен, называемому целевым пространством имен модуля. Это могло бы быть упаковано по-другому, но разница была бы очень поверхностной. Что именно, по вашему мнению, не так с решением выровнять модули с пространствами имен?

...