targetNamespace и xmlns без префикса, в чем разница? - PullRequest
70 голосов
/ 25 августа 2011

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

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

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

Ответы [ 6 ]

76 голосов
/ 26 августа 2011

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

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

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

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

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

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

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

19 голосов
/ 03 марта 2016

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

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

14 голосов
/ 07 ноября 2013

xmlns

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

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

targetNameSpace

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

xmlns: tns

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

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

3 голосов
/ 11 апреля 2017

Пространство имен означает как область действия

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

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

Например:

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

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

enter image description here

1 голос
/ 05 июля 2019

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...