Ответ 1
Первое, что вам нужно понять, это пространство имен XML. Если у вас есть время тратить время, вы можете прочитать спецификацию. Я нашел это одним из более четких спецификаций, связанных с XML. Неважно, не понимаете ли вы все, что он говорит, это хорошая основа. Но вот краткое изложение.
Элементы и атрибуты XML имеют имя. Когда вы видите <test att="hello"/>
, вы смотрите на элемент с именем "test", в котором у нас есть атрибут с именем "att". Но на самом деле это не вся история...
XML - это синтаксис, который позволяет смешивать контент с разных языков разметки. Например, при использовании XSLT для преобразования XML-документа на страницу XHTML вы имеете дело с по меньшей мере тремя языками разметки, определенными в XML: вашими входными документами, XSLT и XHTML. Такие смеси стали бы довольно сложными, если бы каждый из них зарезервировал свои собственные имена элементов/атрибутов и никаких конфликтов не было разрешено.
Введите пространства имен XML. Пространство имен XML определяет "сферу", в которой имена элементов и атрибутов имеют фактическую семантику. Элемент "шаблон" имеет четко определенный смысл в пространстве имен XSLT. Элемент "complexType" имеет четко определенное значение в пространстве имен XML Schema. Если вы хотите использовать либо собственный язык разметки с помощью XML, но это возможно, если вы делаете это в другом пространстве имен.
Чтобы удостовериться, что пространство имен уникально, вам нужно предоставить уникальный идентификатор. Спецификация оговорена на использование URI, чаще всего в виде URL-адреса HTTP. Причина этого проста: такие URL-адреса, как правило, являются хорошими уникальными идентификаторами. Но это также очень распространенная причина для путаницы, потому что люди считают, что URL-адреса действительно имеют смысл или будут доступны по сети во время обработки XML. Знайте, что это не так! URL-адрес не требуется указывать на любой существующий ресурс. Он не пройдет никаких преобразований или не будет разрешен для сетевого адреса. Даже если два URL указывают на то же самое, в тот момент, когда они отличаются одним символом, они считаются разными пространствами имен. Идентификатор пространства имен - это всего лишь строка и чувствительный к регистру. Ничего больше.
С введением пространств имен имя элемента XML или атрибута внезапно состоит из двух частей: пространства имен и локального имени. Этот "тест" в <test/>
- это только локальное имя. Так называемое "полностью квалифицированное имя" состоит из своего рода невидимой комбинации пространства имен и локального имени. Иногда используется нотация {namespace URI}local-name
, но это не что иное, как условное обозначение.
Итак, теперь нам нужно иметь возможность использовать пространства имен в XML-документе. Чтобы объявить пространство имен, XML имеет жестко закодированный механизм. Он использует специальную строку xmlns
, чтобы разрешить объявления пространств имен. Это можно сделать одним из двух способов: привязать пространство имен к префиксу или объявить его как пространство имен по умолчанию.
При привязке к префиксу форма выглядит примерно так: xmlns:prefix="namespace URI"
. Вот пример в документе XML:
<foo:root xmlns:foo="http://www.foo.com">
<foo:test />
</foo:root>
Теперь мы связали пространство имен http://www.foo.com
с префиксом foo
. Везде, где этот префикс помещается перед именем элемента или атрибута, мы заявляем, что они являются частью этого пространства имен.
Важно отметить, что фактический префикс означает абсолютно ничего. Следующий XML-документ семантически то же самое:
<bar:root xmlns:bar="http://www.foo.com">
<bar:test />
</bar:root>
Префикс - это просто удобный способ представления пространства имен. Это избавляет нас от необходимости использовать URI полностью каждый раз.
Далее это пространство имен по умолчанию. По умолчанию пространство имен может быть объявлено с помощью xmlns="namespace URI"
. Вы могли бы абстрактно думать об этом как о привязке пространства имен к пустому префиксу. Еще раз тот же XML-документ, но на этот раз без префиксов:
<root xmlns="http://www.foo.com">
<test />
</root>
Это немного удобнее для работы. Так почему у вас есть префиксы? Они начинают играть роль, когда мы смешиваем контент из разных пространств имен:
<root xmlns="http://www.foo.com">
<so:test xmlns:so="http://stackoverflow.com" />
</root>
На этот раз это другой XML-документ. Наш root
элемент лежит в пространстве имен http://www.foo.com
, но элемент test
находится в http://stackoverflow.com
, потому что мы привязаны к этому префиксу so
и использовали его на test
.
Вы также заметили, что пространства имен могут быть объявлены на любом элементе XML-документа. область этого объявления (и привязка к префиксу, если применимо), затем становится этим элементом и его содержимым.
Это может иногда запутываться, тем более, что объявления могут переопределять друг друга. Проверьте этот документ:
<root xmlns="http://www.foo.com">
<test />
<so:test xmlns:so="http://www.stackoverflow.com" xmlns="http://www.bar.com">
<test />
</so:test>
</root>
Возьмите момент и выясните, какое пространство имен находится в каждом элементе... Это хорошее упражнение.
root
находится в пространстве имен http://www.foo.com
. Первый элемент test
также находится в этом пространстве имен, так как мы не использовали префикс, но мы находимся в области этого пространства имен по умолчанию. Второй элемент test
с префиксом so
лежит в пространстве имен http://www.stackoverflow.com
, потому что мы привязали префикс к.
Итак, тогда есть третий, самый внутренний элемент test
. В каком пространстве имён? Он не имеет префикса, поэтому он должен находиться в пространстве имен по умолчанию. НО, мы изменили пространство имен по умолчанию во втором тестовом элементе! Итак, теперь самый внутренний элемент принадлежит пространству имен http://www.bar.com
, а не http://www.foo.com
.
Смущенный еще? Просто запомните следующее:
- Пространство имен - это просто строка. URI используются как удобный способ иметь уникальные идентификаторы.
- Префикс используется для представления пространства имен, но его имя не имеет никакого значения. Просто подумайте об этом как заполнителе.
- Вы можете установить пространство имен по умолчанию. Все элементы в пределах своей области, которые не имеют префикса, затем становятся его частью.
Уф. Теперь на W3C XML Schema. Как все это относится к этому?
Ну, для начала XML Schema - это язык разметки, определенный в XML. Поэтому разумно, что он получает свое собственное пространство имен. И это пространство имен официально http://www.w3.org/2001/XMLSchema
. Если вы напишете, что S
в нижнем регистре, это неправильно. Исследуя, почему некоторые люди действительно ненавидят пространства имен?
Следующие три документа точно такие же:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
</xsd:schema>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
</xs:schema>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
</schema>
Все, что имеет значение, это то, что мы используем материал из пространства имен XML Schema. Однако, как правило, люди склонны использовать префикс xs
или xsd
в XML-схемах.
Когда у нас есть документ XML, мы можем указать, где расположены его схемы (ы). Более чем одна схема может иметь отношение к XML-документу, поскольку, как мы уже говорили, языки могут быть смешаны в XML. Чтобы сказать, что XML-документ является экземпляром схемы, еще раз есть специальное пространство имен: http://www.w3.org/2001/XMLSchema-instance
. По соглашению мы склонны связывать это пространство имен с префиксом xsi
. Но опять же это необязательно.
В этом пространстве имен экземпляров схемы есть несколько атрибутов. Среди них schemaLocation
и noNamespaceSchemaLocation
. Взгляните на этот документ:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.foo.com/schema">
</root>
Что там? Сначала мы заявили, что мы привязываем префикс xsi
к пространству имен http://www.w3.org/2001/XMLSchema-instance
. Затем мы используем атрибут в этом пространстве имен: noNamespaceSchemaLocation
. Этот атрибут указывает нам, где находится схема, для проверки тех частей документа, которые не находятся в каком-либо конкретном пространстве имен. Следующий XML-документ является точно таким же, семантически:
<root xmlns:huh="http://www.w3.org/2001/XMLSchema-instance" huh:noNamespaceSchemaLocation="http://www.test.com/schema">
</root>
Помните, что имена префиксов не имеют значения. Они являются заполнителями. Итак, что с этим атрибутом noNamespaceSchemaLocation
? В основном, это говорит нам, где мы можем найти схему. Теперь, вопреки URI пространства имен, это определенно то, что можно использовать для извлечения материала из сети или локального хранилища. Обработчик XML, который проверяет схему, объявленную в документе, может попытаться ее получить.
Тогда существует тот факт, что он называется noNamespaceSchemaLocation
. Схема определяет "целевое пространство имен". Что это означает, указывается, какое пространство имен содержит элементы и атрибуты, которые они определяют. Но целевое пространство имен может быть опущено. В этом случае у нас есть схема для документов XML без пространства имен. На такую схему можно ссылаться на noNamespaceSchemaLocation
.
Во многих случаях схема фактически определяет пространство имен. Чтобы указать, к какой схеме принадлежит пространство имен, мы можем использовать другой атрибут из пространства имен http://www.w3.org/2001/XMLSchema-instance
: schemaLocation
. Этот атрибут может содержать пары (разделенные пробелами) URI пространства имен и URI схемы. Предположим, что у нас есть схема для пространства имен http://www.foo.com
, расположенного в http://www.myschemas.com/foo-schema
. Тогда мы можем утверждать, что следующим образом:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.foo.com http://www.myschemas.com/foo-schema">
</root>
Вот пример с несколькими парами пространства имен:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.foo.com http://www.myschemas.com/foo-schema http://www.bar.com http://www.randomschemas.com/bar-schema">
</root>
Что вам нужно запомнить здесь, так это то, что материал http://www.w3.org/2001/XMLSchema-instance
предназначен для использования в документах XML, являющихся экземплярами схем. Пространство имен http://www.w3.org/2001/XMLSchema
- это тот, который используется для определения самих схем.
Итак, теперь мы подходим к нашей шее в URI и странных атрибутах со специальными значениями. Это вещь с пространствами имен: они выглядят очень сложными, пока вы не выясните, насколько они просты. Просто внимательно следите за тем, какой префикс связан с каким URI пространства имен и знает, что определяет этот URI.
Еще две вещи о схемах, которые мне нужно решить для вашего вопроса: xs:import
и xs:include
. Обратите внимание, как я использовал здесь префикс xs
, так как мы говорим о схеме XML W3C.
Элемент include может использоваться для объединения схем с тем же целевым пространством имен. В основном это позволяет нам модулировать схемы на более мелкие части и объединять их.
Элемент import делает то же самое, но для схем с разными целевыми пространствами имен. Это позволяет нам комбинировать схемы для разных языков разметки.
Итак, чтобы повторить:
-
xmlns
: используется для указания пространства имен по умолчанию. -
xmlns:prefix
: используется для привязки пространства имен кprefix
. -
http://www.w3.org/2001/XMLSchema
: пространство имен для XML-схемы. По соглашению часто привязывается к префиксуxs
, но это не является обязательным и не выполняется автоматически. -
http://www.w3.org/2001/XMLSchema-instance
: пространство имен, которое определяет кучу вещей, полезных для объявления деталей того, как XML-документ является экземпляром схемы. По соглашению часто привязывается к префиксуxsi
, но это не обязательно и не выполняется автоматически. -
targetNamespace
: атрибут, который может использоваться в XML-схеме (в корневом элементе), чтобы указать, для какого пространства имен это определение схемы. -
schemaLocation
: один из атрибутов, определяемых пространством именhttp://www.w3.org/2001/XMLSchema-instance
, используемый для указания того, где одна или несколько схем могут быть найдены для одного или нескольких пространств имен.
Мой последний совет: найдите удобный способ проверки документов по схемам и немного поиграйте. Экспериментируйте с пространствами имен, включая и импортируйте. Сделайте документы с использованием нескольких пространств имен и опробуйте область обзора.
После этого проверьте спецификации самого XML, пространства имен XML и схему XML. Это хардкорное чтение, но если вы пройдете через него, вы поймете, что многие люди все еще, кажется, пропустили после многих лет использования XML. В конечном итоге все это будет иметь смысл.
Удачи!