Коротко о пространствах имен (XML Namespaces)
Введение
При создании XML-документа мы можем столкнуться с тем, что разные по смыслу элементы будут иметь одинаковое имя. Вы можете увидеть пример в статье «10 главных ошибок RSS» в пункте 5 «Неправильное расширение RSS».
Разберём пример, явно «притянутый за уши», зато простой для понимания. Нам необходимо сделать выборку из двух таблиц базы данных, касающихся творчества некоего музыкального коллектива и сформировать каталог в виде XML-документа. В одной таблице базы данных содержится информация об аудио записях коллектива, в другой – информация о книгах посвященных его творчеству. По какой-то причине (непонятно какой, но очень важной), и описание аудио записей и описание книг должно содержаться в элементе «item». По той же причине, и названия записей и названия книг должны содержаться в элементе «title».
В результате получаем, что-то вроде этого:
1 2 3 4 5 6 7 8 | <catalog> <item> <title /> </item> <item> <title /> </item> </catalog> |
Налицо конфликт имен, так как сложно определить, какой вид данных содержит каждый из элементов «item» и «title». Первый блок «item» относится к дискографии и элемент «title» содержит название диска. Второй блок «item» относится к библиографии и элемент «title» содержит название книги. Для предотвращения подобного конфликта нам надо разделить эти группы логически. Делается это заданием пространства имен: одни элементы относятся к имени «music», другие — к имени «book». Для объявления пространствa имeн используeтся атрибут имя которого состоит из зарезервированного слова «xmlns», после которого следует двоеточие и, собстветнно, само имя:
xmlns:music = "http://ininfo.biz/music"
Первый вопрос, который возникает, что использовать в качестве значения атрибута «xmlns»? Для того, чтобы обеспечить уникальность пространства имен надо использовать какой-либо URI (Uniform Resource Identifier, Унифицированный Идентификатор Ресурса), проще говоря — уникальную строку, которая будет однозначно идентифицировать данный элемент*. Многие используют в качестве идентификатора URL, так как имена доменов, которые используются в URL являются уникальными. Кроме того, вряд ли кто-нибудь будет использовать адрес «http://ininfo.biz/book» кроме его владельца, так что конфликт исключен.
Пространства имен для элементов
Указание на то, к какому пространству имен относится тот или иной элемент, записывается перед началом имени элемента с разделителем в виде двоеточия:
<music:title />Исходя из вышеизложенного, в принципе, можно объявить пространство имен для каждого элемента, который используется в документе:
1 2 3 4 5 6 7 8 | <catalog> <music:item xmlns:music = "http://ininfo.biz/music"> <music:title xmlns:music = "http://ininfo.biz/music" /> </music:item xmlns:music = "http://ininfo.biz/music"> <book:item xmlns:book = "http://ininfo.biz/book"> <book:title xmlns:book = "http://ininfo.biz/book" /> </book:item xmlns:book = "http://ininfo.biz/book"> </catalog> |
Согласитесь, это не самый лучший вариант, так как во-первых, надо набирать много текста; во-вторых, такой код сложно читать; в-третьих, легко наделать ошибок. Можно поступить другим образом используя правило:
Пространство имен объявленное для какого-либо элемента, является таковым для всех вложенных в него элементов, если для них не объявлено других пространств имен.
1 2 3 4 5 6 7 8 | <music:catalog xmlns:music = "http://ininfo.biz/music"> <music:item> <music:title /> </music:item> <book:item xmlns:book = "http://ininfo.biz/book"> <book:title /> </book:item> </music:catalog> |
Можно поступить еще проще — объявить все пространства имен за один раз в корневом элементе:
1 2 3 4 5 6 7 8 9 10 | <music:catalog xmlns:music = "http://ininfo.biz/music" xmlns:book = "http://ininfo.biz/book"> <music:item> <music:title /> </music:item> <book:item> <book:title /> </book:item> </music:catalog> |
Однако надо помнить, что идентификатором пространства имен является значение атрибута «xmlns», а не его название-префикс. В следующем примере все элементы принадлежат одному пространству(значение атрибута равно «http://ininfo.biz/group») хотя и имеют разные имена-префиксы(«music» и «book»):
1 2 3 4 5 6 7 8 9 10 | <music:catalog xmlns:music = "http://ininfo.biz/group" xmlns:book = "http://ininfo.biz/group"> <music:item> <music:title /> </music:item> <book:item> <book:title /> </book:item> </music:catalog> |
Допускается и обратное — элементы имеют различные пространства имен, но используют одинаковые имена-префиксы:
1 2 3 4 5 6 7 8 | <catalog> <group:item xmlns:group = "http://ininfo.biz/music"> <group:title /> </group:item> <group:item xmlns:group = "http://ininfo.biz/book"> <group:title /> </group:item> </catalog> |
Можно обойтись и без имен-префиксов. Для этого надо задать пространство имен по-умолчанию. В этом случае, данное пространство будет использоваться для элемента, в котором он встречается и для всех его дочерних(вложенных) элементов:
1 2 3 4 5 6 7 8 | <catalog> <item xmlns = "http://ininfo.biz/music"> <title /> </item> <item xmlns = "http://ininfo.biz/book"> <title /> </item> </catalog> |
Для того, чтобы отменить пространство имен заданное по-умолчанию, необходимо присвоить атрибуту «xmlns» значение пустой строки:
1 2 3 4 5 6 7 8 9 | <catalog xmlns = "http://ininfo.biz/group"> <item> <title /> </item> <item xmlns = ""> <title /> </item> </catalog> |
Пространства имен для атрибутов элементов
Также как и элементы, к заданному пространству имен могут быть отнесены и их атрибуты:
1 2 3 4 5 6 7 8 9 10 | <music:catalog xmlns:music = "http://ininfo.biz/music" xmlns:book = "http://ininfo.biz/book"> <music:item music:number="10"> <music:title book:numref="20" /> </music:item> <book:item book:number="20"> <book:title music:numref="10" /> </book:item> </music:catalog> |
Однако пространство имен по-умолчанию на атрибуты не распостраняется. Если у атрибута не указан префикс, то он не принадлежит ни к одному пространству имен:
1 2 3 4 5 6 7 8 9 10 | <music:catalog xmlns:music = "http://ininfo.biz/music" xmlns:book = "http://ininfo.biz/book"> <music:item music:number="10"> <music:title numref="20" /> </music:item> <book:item book:number="20"> <book:title numref="10" /> </book:item> </music:catalog> |
Вышеизложенное верно и для случая, когда пространство имен задано для элемента, к которому принадлежит атрибут, например:
<music:item number="10" xmlns:music = "http://ininfo.biz/music">
Чтобы совсем запутаться, можно отметить, что объявление пространства имен действует в рамках того элемента, в котором оно встречается:
1 2 3 4 5 6 7 8 9 | <root xmlns:primer = "http://ininfo.biz/one"> <primer:el1 xmlns:primer = "http://ininfo.biz/two"> <primer:el2 /> <el3 xmlns:primer = "http://ininfo.biz/three"> <primer:el2 /> </el3> </primer:el1> <primer:el2 /> </root> |
Возможно, эта статья будет дополнена. Поэтому, продолжение следует и следите за обновлениями.
«У гражданина РФ уникальным идентификатором может считаться его ИНН…»
Для ultra-параноиков в Microsoft изобрели GUID’ы (глобальные уникальные идентификаторы) и алгоритм их генерации (функция встроена в win32, можно погуглить софт). Это тем, кому нужна 100500% гарантия уникальности
Свой ИНН писать же где ни поподя, я думаю, ненадо, как и телефон, аську и адрес проживания…