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

TargetNamespace и xmlns без префикса, в чем разница?

В документе схемы xml, если у меня есть как targetNamespace, так и xmlns без префикса.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://example.com/" xmlns="http://example.com/">

Какая разница между ними? Мое понимание заключается в том, что если у вас есть xmlns без префикса, все элементы без префикса получат это пространство имен и... путано то же самое касается targetNamespace.

4b9b3361

Ответ 1

targetNamespace - это артефакт XML-схемы; его цель: указать, какое конкретное пространство имен XML описывает файл схемы.

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

По моему опыту, многие авторы XML Schema считают это "лучшей практикой"... так что вы на правильном пути.

В терминах XSD, targetNamespace предписывает часть пространства имен квалифицированного имени компонента схемы, которая включает в себя элементы, атрибуты, группы и группы атрибутов, а также простые и сложные типы. Некоторые из квалифицированных имен, определенных в XSD (элементы и атрибуты), "непосредственно" используются документом экземпляра XML. Другие, например, для типов, можно ссылаться через атрибут xsi: type в экземплярах XML-документов. Остальные (группы, группы атрибутов) используются для облегчения составления схемы (посредством ссылок).

Я также считаю, что (в общем) люди придумывают XSD с двух сторон:

  • чтобы соответствовать существующему XML. В этом случае, если ваш XML использует пространства имен, для каждого из используемых пространств имен вы получите элемент схемы XSD с соответствующим атрибутом targetNamespace.

  • чистое моделирование. Затем вы думаете о targetNamespace, похожем на UML-пакет, или схему базы данных, или пакет Java, или пространство имен .NET, и все это означает в этом случае. По сути, это механизм, позволяющий избежать коллизий имен; тем не менее, это также механизм разделения моделей в предметных областях и т.д.

Ответ 2

Для тех, кто все еще запутался, рассмотрите эти три xsds. Все они определяют один глобальный тип и одно глобальное определение элемента, которое ссылается на него.

Во-первых, xsd, как тот, который был выше. Он использует префикс 'xsd' для пространства имен схемы и пространство имен по умолчанию для targetNamespace:

<xsd:schema 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://example.com/" 
  xmlns="http://example.com/">

  <xsd:element name="aGlobalElement" type="aGlobalType"/>

  <xsd:simpleType name="aGlobalType">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>   
</xsd:schema>  

Теперь тот же xsd, но определяющий и использующий префикс пространства имен для целевого пространства имен:

<xsd:schema 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://example.com/" 
  xmlns:tns="http://example.com/">

  <xsd:element name="aGlobalElement" type="tns:aGlobalType"/>

  <xsd:simpleType name="aGlobalType">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType> 
</xsd:schema>  

... и, наконец, версия, которая использует пространство имен по умолчанию вместо "xsd" для пространства имен схемы XML:

<schema 
  xmlns="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://example.com/" 
  xmlns:tns="http://example.com/">

  <element name="aGlobalElement" type="tns:aGlobalType"/>

  <simpleType name="aGlobalType">
    <restriction base="string"/>
  </simpleType>
</schema>

Большинство авторов схемы выбирают первый или последний, потому что, если доступно пространство имен по умолчанию, мы могли бы использовать его для чего-то.

Ответ 3

XMLNS

Атрибут xmlns задает пространство имен по умолчанию описанного элемента. Таким образом, пространство имен по умолчанию применяется ко всем элементам внутри описанного элемента, которые явно не объявляют другое пространство имен для себя.

По умолчанию для пространства имен установлено стандартное значение для файлов WSDL: http://www.w3.org/ns/wsdl

TargetNamespace

Этот атрибут содержит пространство имен вашего веб-сервиса. Вы можете свободно выбирать это пространство имен, но есть соглашение о том, что URI должен указывать на WSDL службы.

Xmlns: ТНС

Это пространство имен должно быть установлено в тот же URI, что и атрибут targetNameSpace. Таким образом вы можете обратиться к целевому пространству имен с помощью этого префикса пространства имен (tns).

Источник: http://tutorials.jenkov.com/wsdl/description.html

Ответ 4

пространство имен означает как область

targetNamespace - это атрибут элемента schema определяющий пространство имен, т.е. пакет в файле XSD. По соглашению мы используем URI/URL, но мы можем использовать любую строку.

xmlns - это атрибут, используемый для ссылки на элементы и типы данных, которые поступают из значения атрибута xmlns для текущей области элемента.

Например:

  • xmlns:xsd="http://www.w3.org/2001/XMLSchema" с префиксом, поскольку xsd означает, что пространство имен должно иметь префикс xsd:
  • xmlns="http://www.w3.org/2001/XMLSchema" без префикса по умолчанию
  • xmlns: p = "http://www.example.com/People" с префиксом, поскольку p означает, что пространство имен должно иметь префикс p:

Где xmlns:xsd и xmlns:p - QNames, а xmlns - локальное имя.

Следующее изображение помогает понять XSD, используя аналогию с Java, насколько мне известно:

enter image description here

Ответ 5

Ни один из приведенных выше ответов не имел смысла для меня, пока я не прочитал что-то на веб-сайте Microsoft. Может быть, это поможет кому-то понять разницу между "targetNamespace" и "xmlns".

"Xmlns" делает одну вещь: он устанавливает пространство имен по умолчанию для всех xml (элементов и атрибутов) ВНУТРИ только вашего файла схемы.

"TargetNamespace" выполняет две функции: он изменяет пространство имен по умолчанию, заданное вами с помощью "xmlns", на новое пространство имен в файле схемы И устанавливает пространство имен для всех документов xml, полученных из него, а не внутри него. Единственным исключением является то, что его собственные элементы ссылаются на свои собственные типы внутри схемы (см. Ниже).

Давайте углубимся в детали, чтобы понять, что это значит:

"TargetNamespace" в схеме просто говорит синтаксическому анализатору переместить пространство имен из пространства по умолчанию в пространство имен "targetNamespace", где "xmlns" устанавливает пространство имен по умолчанию до того, как будет установлено "targetNamespace". "TargetNamespace" нельзя использовать, пока вы не установили пространство имен по умолчанию с помощью "xmlns".

Пример. Это работает, поскольку пространство имен по умолчанию было установлено сначала, а затем изменено:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="abc" targetNamespace="def">

Это терпит неудачу, поскольку сначала не установлено пространство имен по умолчанию:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="def">

Вышеприведенное приведет к ошибке, поскольку не определено xmlns = 'xxxxx' или пространство имен по умолчанию. Если вы добавите атрибут "targetNamespace" со значением в схему, для которой не определено пространство имен - т.е. у него пустое пространство имен или xmlns = "" - вы получите ошибку. Зачем? Вы получаете сообщение об ошибке, потому что не можете изменить пространство имен, если оно еще не было установлено или пусто. Кстати... xmlns = "" - это то же самое, что пустое, пустое или пустое пространство имен в мире XML. Но это первое правило.

Затем выясняется, что каждый документ XML или документ схемы имеет пустое пространство имен по умолчанию. Это то же самое, что сказать xmlns = "". Когда вы добавляете атрибут "xmlns = 'xxxxx'" со значением, вы устанавливаете каждый тег и атрибут в файле xml в новое пространство имен по умолчанию. Вы не можете добавить "targetNamespace" до тех пор, пока оно не будет установлено, что является ИЗМЕНЕНИЕМ в пространстве имен для каждого тега в XML.

Давайте теперь поговорим о том, как используется новое пространство имен по умолчанию.

Когда вы устанавливаете для атрибута "xmlns" значение, вы просто говорите: сначала установите пространство имен по умолчанию, используя "xmlns". Позже, конечно, вы можете изменить его, даже на то же пространство имен по умолчанию, используя "targetNamespace" следующим образом:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="abc" xmlns="abc">

Вышеуказанное означает, что вы задали пространство имен по умолчанию для схемы, а затем снова сбросили его до значения по умолчанию. "xmlns" должен быть установлен первым, а "targetNamespace" - вторым. Конечно, вы можете сделать их разными.

Одно замечание об использовании цели с пустым пространством имен. Вы можете добавить "targetNamespace" в качестве дочерней ссылки или псевдонима в пустое пространство имен следующим образом. Это довольно часто:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="abc" xmlns:tns="abc">

Но что это значит? Пространство имен по умолчанию остается пустым (xmlns = ""), но псевдоним "tns" теперь доступен как дочерний элемент пустого пространства имен и используется для определения определенных элементов внутри вашего xml с использованием нового targetNamespace. В этом сценарии у вас есть пустое пространство имен, но определенные атрибуты внутри вашей схемы будут иметь свое собственное пространство имен с использованием псевдонима, например:

<xs:element name="hello" type='tns:MyType' />

Затем это объясняет разницу между двумя атрибутами, но не объясняет, ПОЧЕМУ вам нужны оба "targetNamespace" и "xmlns".

Оказывается, что установка вашего пространства имен по умолчанию для вашей схемы, "xmlns = 'xxxxx'", но НЕ установка целевого пространства имен, "targetNamespace = 'xxxxx'", установит все ваши теги xml в новое пространство имен, но не будет разрешено снаружи xml-экземпляры, которые используют схему или даже вашу схему для доступа к своим собственным типам.

Таким образом, добавление "targetNamespace" не только меняет пространство имен xmlns по умолчанию, но и контролирует, как схема обращается к своим собственным типам. Например, приведенный ниже пример кода завершается ошибкой, так как в нем отсутствует targetNamespace. Это значение необходимо для того, чтобы схема присвоила пространству имен свой простой тип и получила доступ к этому простому типу из своего собственного элемента схемы ниже. Несмотря на то, что было назначено пространство имен по умолчанию, пользовательский "simpleType", доступный из элемента, не может получить к нему доступ, так как он не был связан с целевым пространством имен схемы. Это объясняет разницу:

<xsd:schema 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns="abc">
  <xsd:element name="myelementname" type="mytype"/>
  <xsd:simpleType name="mytype">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>   
</xsd:schema>

Код ниже будет в порядке, так как targetSchema был добавлен и сообщает схеме, что ее типы также являются частью пространства имен и доступны, и схема может ссылаться на свои собственные типы, используя новое пространство имен без псевдонима.

<xsd:schema 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="abc"
  xmlns="abc">
  <xsd:element name="myelementname" type="mytype"/>
  <xsd:simpleType name="mytype">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>   
</xsd:schema>

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

Ответ 6

Другие ответы здесь хороши, поэтому я не буду повторять их объяснения здесь. Тем не менее, если кто-то из Java-фона, найдет его проще, вот аналогия, которую я придумал:

  1. Документ .xsd представляет собой файл артефакта /.jar
  2. xmlns - это

    package com.example
    

    Заявление, вы объявляете в верхней части ваших классов Java.

Рассмотрим (для аналогии), если у вас был один пакет в вашем проекте Java, и все классы объявлены и определены в одном внешнем классе. Например,

    package com.furniture.models

    public class FurnitureShop {

         int noOfTables;
         int noOfChairs;
         int noOfBeds;
         List<Table> tables;
         List<Chair> chairs;
         List<Bed> beds;

         // and now instead of declaring and defining a class for table/chair/bed in a 
         // separate file, you just add it here 
         public static class Table {
             int height;
             int width;
             int length;
             ...
         }

         public static class Chair {
             String color;
             ChairType chairType;
             ...
         }

         public static class Sofa {
             int price;
             String color;
             ...
         }
    }

Вот как различные элементы группируются в один файл .xsd для новой схемы.

  1. targetNamespace - это имя артефакта, который вы создаете. Как вы можете выяснить сами, targetNamespace используется при создании схемы в файле .xsd.

После создания артефакта (или файла .xsd) его можно использовать в других проектах следующим образом:

В проекте Java вы должны импортировать библиотеку, используя pom.xml (или build.gradle) следующим образом:

    <dependency>
       <groupId>com.furniture</groupId>
       <artifactId>furniture-apis</artifactId>
       <version>1.1.1</version>
    </dependency>

В XML вы "импортируете" схему, используя

    <furniture xmlns="http://furniture.com"/>

=== ПРИЛОЖЕНИЕ ===

Пояснение -

  1. xmlns используется как оператор package, а также как оператор import в Java. В файле .xsd xmlns действует как оператор " package ", тогда как в файлах .xml он действует как оператор " import ".

Ответ 7

После тщательного тестирования с использованием xmllint, я думаю, что нашел здесь определенное объяснение. Рассмотрим приведенную ниже схему:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://yyyzzz.com"
xmlns:p="http://abced.com"
xmlns:q="http://pqr.com"
xmlns="http://yyyzzz.com">

<xsd:element name="recipe" type="recipeType" />

<xsd:complexType name="recipeType">
    <xsd:simpleContent>
        <xsd:extension base="xsd:string">
        <xsd:attribute name="desc" type="xsd:string"  />
        <xsd:attribute name="archetype" type="xsd:string" />
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>
</xsd:schema>

Вышеприведенная схема проверяет следующий документ:

<?xml version="1.0"?>

<recipe xmlns="http://yyyzzz.com">
    Deciphering the purpose of targetNamespace
</recipe>

Причина, по которой работает, состоит в том, что xmlns = "http://yyyzzz.com" автоматически связывается с элементом, который также определяется схемой! Это означает, что он также привязывается к элементу recipeType.

Теперь, с тем же документом xml, но с немного модифицированной схемой, как показано ниже, также проверяется и внимательно изучает разницу:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://yyyzzz.com"
xmlns="http://eigenfield.aparicio.com"
xmlns:EGboy="http://yyyzzz.com">

<xsd:element name="recipe" type="EGboy:recipeType" />

<xsd:complexType name="recipeType">
    <xsd:simpleContent>
        <xsd:extension base="xsd:string">
        <xsd:attribute name="desc" type="xsd:string"  />
        <xsd:attribute name="archetype" type="xsd:string" />
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

</xsd:schema> 

Игнорируйте, если отсутствует xmlns, но посмотрите внимательно на type = "EGboy: recipeType" . Мы больше не можем полагаться на xmlns, потому что он имеет различное значение, поэтому мы должны поставить префикс EGboy перед recipeType.

Документ xml даже не заботится о префиксе EGboy, этот префикс предназначен только для того, чтобы схема ссылалась на соответствующие xmlns, если их много.