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.

5 ответов

Решение

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

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

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

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

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

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

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

Для тех, кто все еще в замешательстве, рассмотрим эти три 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>

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

XMLNS

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

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

TargetNamespace

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

Xmlns: ТНС

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

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

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, насколько мне известно:

введите описание изображения здесь

Другие ответы здесь хороши, поэтому я не буду здесь повторять их объяснения. Однако, если кто-то из знакомых с 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" заявление.

После некоторого тщательного тестирования с использованием 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, если их много.

Другие вопросы по тегам