targetNamespace та xmlns без префіксу, в чому різниця?


77

У документі схеми xml, якщо я маю і targetNamespace, і xmlns без префікса .

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

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


1
Можливо, мені бракує певних знань з цього питання, але чи не могла відповісти просто така: xmlns - це простір імен за замовчуванням для ЦЕОГО документа (документа схеми), тоді як targetNamespace - це простір імен, який цей документ схеми перевіряє? І таким чином xmlns і targetNamespace - це дві різні речі?
Вихід

@За результатами мого тесту узгоджується з вашим першим реченням, так targetNamespace однозначно посилається на документ, який перевіряє схема. Присутність targetNamespace, здається, також потребує присутності або 'xmlns', або 'xmlns: xxx'. Насправді ви можете поєднати багато 'xmlns: xxx', 'xmlns: yyy' та 'xmlns' разом, і це все ще перевіряє.
eigenfield

Відповіді:


80

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, і все це означає в цьому випадку. По суті, це механізм уникнення зіткнень імен; тим не менше, це також механізм розділення моделей на предметні області тощо.


28

Для тих, хто все ще розгублений, розгляньте ці три 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>

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


15

xmlns

Атрибут xmlns встановлює простір імен за замовчуванням для описаного елемента. Таким чином, простір імен за замовчуванням застосовується до всіх елементів всередині описаного елемента, які явно не оголошують інший простір імен для себе.

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

targetNameSpace

Цей атрибут містить простір імен вашої веб-служби. Ви можете вільно вибирати цей простір імен, але існує умова, згідно з якою URI повинен вказувати на WSDL служби.

xmlns: tns

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

Джерело: http://tutorials.jenkov.com/wsdl/description.html


URI для targetNamespace нічого не "вказує" - це лише ідентифікатор простору імен. Це може бути URI веб-служби, але це все одно лише для позначення простору імен.
Suncat2000

4

простір імен означає, як область

targetNamespaceє атрибутом schemaелемента, що визначає простір імен, тобто пакет у файлі XSD. За домовленістю ми використовуємо URI / URL-адреси, але ми можемо використовувати будь-який рядок.

xmlns is атрибут використовується для посилання на елементи та типи даних, що походять із значення атрибута 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:pQNames іxmlns це місцева назва.

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

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


1

Інші відповіді тут хороші, тому я не буду тут повторювати їх пояснення. Однак, якщо хтось із фонів 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".

-1

Після ретельного тестування за допомогою 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" автоматично прив'язується до елемента, який також визначається схемою! Це означає, що він також прив'язується до елемента receptType .

Тепер, з тим самим документом 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 перед receptuType .

Документ xml навіть не піклується про префікс EGboy; цей префікс призначений лише для того, щоб схема посилалася на належні xmlns, якщо їх багато.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.