Пространства имен (namespaces) Пространства имен (namespaces) • Пространства имен имеют в XML два применения: 1. Для различия одноименных элементов и атрибутов из разных XMLприложений. 2. Для группировки всех связанных элементов и атрибутов одного XMLприложения, что облегчает программному обеспечению их распознавание. • Первое применение проще объяснить и усвоить, однако второе на практике важнее. • Пространства имен реализуются присоединением префикса к каждому элементу и атрибуту. • Каждому префиксу ставится в соответствие URI. • Можно также указать URI по умолчанию для элементов без префикса. • Элементы и атрибуты, присоединенные к одному URI, находятся в одном пространстве имен. • Для элементов из многих XML-приложений определены стандартные URI. • Пространства имен указывается с помощью присоединения префикса к каждому элементу и атрибуту. • Каждому префиксу ставится в соответствие URI. • Можно также указать URI по умолчанию для элементов без префикса. • Элементы и атрибуты, присоединенные к одному URI, находятся в одном пространстве имен. • Для элементов из многих XML-приложений определены стандартные URI. Для чего нужны пространства имен • Некоторые документы сочетают разметку из нескольких XMLприложений. – Например, документ XHTML может содержать и рисунки в формате SVG, и выражения MathML. – Таблица стилей XSLT включает как инструкции XSLT, так и элементы из словаря результирующего дерева. – Ссылки XLink также всегда находятся в связи с элементами документа, в котором они присутствуют, так как в самой спецификации XLink определяются только атрибуты и не определяются никакие элементы. • В некоторых случаях эти приложения могут использовать одно и то же имя для обозначения разных вещей. – Например, элемент set в SVG –это абстрактный контейнер, с помощью которого общее свойство присваивается группе элементов, в то время как элемент set в MathML обозначает математическое множество, например множество всех положительных четных чисел. – Нужно различать, когда подразумевается set из MathML, а когда set из SVG; иначе при проверке действительности, отображении, индексировании и других действиях произойдет путаница и сбой. Пример - Список картин • Пример простого списка картин, включающий название, дату создания, имя художника и описание каждой картины. <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <catalog> <painting> <title>Воспоминания о саде в Эттене</title> <artist>Винсент Ван Гог</artist> <date>Ноябрь, 1888</date> <description> Две женщины смотрят налево. Третья работает в саду. </description> </painting> <painting> <title>Качели</title> <artist>Пьер-Огюст Ренуар</artist> <date>1876</date> <description> Девушка на качелях. Двое мужчин и ребенок смотрят. </description> </painting> <!-- И много других картин... --> </catalog> • • • Предположим, что данный пример используется в качестве web-страницы, и нужно, чтобы эта страница была доступна поисковым машинам. Один из вариантов – вставить на страницу метаданные с помощью Resource Description Framework. Таким образом можно создать описание страницы для любой поисковой системы или другого заинтересовавшегося ею робота. При использовании Dublin Core (http://purl.oclc.org/dc/), стандартного словаря метаданных для информации в стиле библиотечного каталога, закодированной в XML или в другом синтаксисе, RDF-описание этой страницы может выглядеть следующим образом: <RDF> <Description about="http://ibiblio.org/examples/impressionists.xml"> <title> Картины импрессионистов </title> <creator> Elliotte Rusty Harold </creator> <description> Список знаменитых импрессионистских картин, организованный по художникам и датам </description> <date>2000-08-22</date> </Description> </RDF> • Здесь встречаются элементы Description и RDF из RDF и элементы title, creator, description и date из Dublin Core. – Эти имена заданы соответствующими спецификациями. • Если мы хотим, чтобы стандартное программное обеспечение, понимающее RDF и Dublin Core, понимало и созданные документы, требуется использовать эти имена. Пример объединения описания со списком картин: <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <catalog> <RDF> <Description about="http://ibiblio.org/examples/impressionists.xml"> <title> Картины импрессионистов </title> <creator> Elliotte Rusty Harold </creator> <description> Список знаменитых импрессионистских картин, организованный по художникам и датам </description> <date>2000-08-22</date> </Description> </RDF> <painting> <title>Воспоминания о саде в Эттене</title> <artist>Винсент Ван Гог</artist> <date>Ноябрь, 1888</date> <description> Две женщины смотрят налево. Третья работает в саду. </description> </painting> <painting> <title>Качели</title> <artist>Пьер Огюст Ренуар</artist> <date>1876</date> <description> Девушка на качелях. Двое мужчин и ребенок смотрят. </description> </painting> <!-- И много других картин... --> </catalog> Синтаксис пространств имен • Пространства имен устраняют противоречия между одноименными элементами путем назначения элементам и атрибутам URI. • Как правило, всем элементам из одного XML-приложения назначается один URI, а всем элементам и атрибутам из другого XMLприложения –другой URI. • URI делят элементы и атрибуты на не пересекающие множества. – элементы с одним именем, но разными URI, являются разными элементами; – элементы с одним именем и одинаковым URI – одинаковыми. • Обычно существует однозначное соответствие между пространствами имен и XML-приложениями, однако в некоторых приложениях используется несколько пространств имен для разделения различных частей приложения. – Например, в XSL используются различные пространства имен для XSL Transformations (XSLT) и XSL Formatting Objects (XSLFO). Префиксы • Так как URI часто содержат такие символы, как ‘/’, ‘%’ и ‘~’, которые не допустимы для XML-имен, в именах элементов и атрибутов вместо URI используются краткие префиксы, – Например: rdf и xsl • Каждый префикс ставится в соответствие только одному URI. • Имена с префиксами, связанными с одним URI, принадлежат одному пространству имен. • Имена с префиксами, связанными с разными URI, относятся к разным пространствам имен. • Имена элементов и атрибутов в пространствах имен содержат ровно одно двоеточие: rdf:description xlink:type xsl:template • Префикс – это все, что идет перед двоеточием. • Локальная часть – это все, что идет после двоеточия. • Полное имя, включая двоеточие, называется уточненным именем (qualified name), или QName. – Префикс определяет пространство имен, к которому относится элемент или атрибут. – Локальная часть идентифицирует конкретный элемент или атрибут в пределах пространства имен. • Например, в документе, одновременно содержащем элементы set из SVG и из MathML, первый можно обозначить как svg:set, а второй – как math-ml:set. – Это устранит путаницу между элементами. • В таблице стилей XSLT, преобразующей документы в форматирующие объекты XSL, XSLT-процессор распознает – элементы с префиксом xsl как XSLT инструкции, – элементы с префиксом fo – как элементы результата. Прификс пространства имен • Префиксы могут содержать любые символы, допустимые в XML-имени, кроме двоеточия. • Префиксы, начинающиеся тремя символами xml (в любой комбинации регистров), зарезервированы для использования XML и относящимися к нему спецификациями. • В остальном можно задавать префиксам любые удобные для вас имена. • Локальная часть имени не может содержать двоеточий. – единственное корректное применение двоеточия в XML – отделение префикса пространства имен от локальной части в уточненном имени. Привязка префиксов к URI • Каждый префикс в уточненном имени должен быть связан с URI. – Например, все элементы XSLT в таблицах стилей XSLT 1.0 связаны с URI http://www.w3.org/1999/XSL/Transform. – Вместо более длинного URI пишется общепринятый префикс xsl. • Соглашения по использованию URI – Нельзя непосредственно использовать URI в имени. (Связано с тем, что слэш, имеющийся в большинстве URI, не является допустимым символом в XML-имени). – Однако ссылка на полное имя без назначения конкретного префикса иногда оказывается полезной. • Префиксы привязываются к URI пространств имен добавлением атрибута xmlns:prefix к элементу с префиксом или одному из его предков (prefix следует заменить на фактически используемый префикс). • Например, атрибут xmlns:rdf этого элемента rdf:RDF привязывает префикс к URI http://www.w3.org /TR/REC-rdf-syntax#: <rdf:RDF xmlns:rdf="http://www.w3.org/TR/REC-rdf-syntax#"> <rdf:Description about="http://ibiblio.org/examples/impressionists.xml"> <title>Картины импрессионистов</title> <creator>Elliotte Rusty Harold</creator> <description> Список знаменитых импрессионистских картин, организованный по художникам и датам </description> <date>2000-08-22</date> </rdf:Description> </rdf:RDF> • • Привязка действует в пределах элемента, в котором она объявлена, и его содержимого. • Атрибут xmlns:rdf объявляет префикс rdf для элемента rdf:RDF и его дочерних элементов. • При обработке приведенного ранее примера, RDF-процессор: – распознает rdf:RDF и rdf:Description, как RDF-элементы, так как оба имеют префиксы, привязанные к определенному URI, указанному в спецификации RDF. – не рассматривает элементы title, creator, description и date как RDFэлементы, так как они не имеют префиксов, привязанных к URI http://www.w3.org /TR/REC!rdf!syntax#. • Префикс может объявляться в элементе самого верхнего уровня, использующем этот префикс, или в любом его предке. • Это может быть как корневой элемент документа, так и элемент более низкого уровня. • Например, элементы Dublin Core могут быть связаны с пространством имен http://purl.org/dc/ путем добавления атрибута xmlns:dc к элементу rdf:Description, потому что все элементы Dublin Core, присутствующие в этом документе, расположены внутри одного элемента rdf:Description. • В документах, в которых элементы разнесены в большей степени, удобнее поместить объявление пространства имен в начальный тег корневого элемента. • Если это необходимо, один элемент может содержать несколько объявлений разных пространств имен. <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <catalog> <rdf:RDF xmlns:rdf="http://www.w3.org/TR/REC-rdf-syntax#"> <rdf:Description xmlns:dc="http://purl.org/dc/” about="http://ibiblio.org/examples/impressionists.xml"> <dc:title> Картины импрессионистов </dc:title> <dc:creator> Elliotte Rusty Harold </dc:creator> <dc:description> Список знаменитых импрессионистских картин, организованный по художникам и датам </dc:description> <dc:date>2000-08-22</dc:date> </rdf:Description> </rdf:RDF> <painting> <title>Воспоминания об Эттенском саде </title> <artist>Винсент Ван Гог</artist> <date>Ноябрь, 1888</date> <description> Две женщины смотрят налево. Третья работает в саду. </description> </painting> <painting> <title>Качели</title> <artist>Пьер Огюст Ренуар</artist> <date>1876</date> <description> Девушка на качелях. Двое мужчин и ребенок смотрят. </description> </painting> <!-- И много других картин... --> </catalog> • DTD данного документа может включать различные модели содержимого для элементов dc:description и description. • Таблица стилей может поставить в соответствие элементам dc:title и title разные стили. • Программное обеспечение, сортирующее каталог по дате, может учитывать элементы date и игнорировать элементы dc:date. • В этом примере элементы без префиксов, такие как catalog, painting, description, artist и title, не принадлежат какому-либо пространству имен. • Кроме того, атрибуты без префикса, такие как about элемента rdf:Description из предыдущего примера, тоже никак не относятся к пространствам имен. • Того факта, что атрибут относится к элементу пространства имен http://www.w3.org/TR/REC!rdf!syntax#, недостаточно для помещения атрибута в это пространство имен. • Атрибут может относиться к пространству имен, только если у него есть объявленный префикс, например: xlink:type и xlink:href. • В пределах документа можно переопределить префикс, так что в одном элементе префикс будет ссылаться на один URI, а в другом элементе – на другой URI. • В этом случае приоритет имеет ближайший объявивший префикс предок. • Однако в большинстве случаев переопределение префиксов – не самая лучшая идея, приводящая только к путанице, и ею не стоит пользоваться на практике. URI идентификаторы URI пространств имен • Для многих XML-приложений имеются общепринятые префиксы. – Например, для элементов SVG часто употребляется префикс svg, – для элементов Resource Description Framework (RDF) – префикс rdf. • Однако эти префиксы являются просто соглашениями и могут меняться в случае необходимости, для удобства или просто так. • Перед тем как использовать префикс, необходимо задать его привязку к URI, например: – http://www.w3.org/2000/svg или – http://www.w3.org/1999/02/22-rdf-syntax!ns#. • Стандартизованы именно URI, а не префиксы. – Префикс может меняться, в то время как URI остается неизменным. • RDF-процессор ищет свой URI, а не определенный префикс. – Пока никто вне домена w3.org не пользуется URI пространств имен в домене w3.org, и пока W3C может отслеживать, какие URI его сотрудники используют для пространств имен, можно избежать любых конфликтов. • URI пространств имен не всегда указывают на реальный документ или страницу. – Фактически они не обязаны следовать схеме http. – Они могут даже использовать другой протокол, такой как mailto, в котором URI вообще не указывает на документы. • Однако, если вы определяете собственное пространство имен с помощью URI с протоколом http, неплохой идеей будет размещение по этому URI информации о вашей спецификации. – Консорциум W3C устал получать сообщения о неверных ссылках на URI пространств имен в своих спецификациях, и потому они добавили соответствующие странички по собственным URI пространств имен. • Тем не менее, это не обязательно. Установка пространства имен по умолчанию с помощью атрибута xmlns • Часто все содержимое определенного элемента взято из одного XML-приложения. – Например, внутри элемента svg, относящегося к Scalable Vector Graphics, очевидно, находятся только другие SVGэлементы. • Можно указать, что элемент без префикса и все его дочерние элементы без префиксов относятся к данному пространству имен, указав для элемента верхнего уровня атрибут xmlns без префикса: <svg xmlns="http://www.w3.org/2000/svg” width="12cm" height="10cm"> <ellipse rx="110" ry="130" /> <rect x="4cm" y="1cm" width="3cm" height="6cm" /> </svg> • • • Пространства имен по умолчанию относятся только к элементам, а не к атрибутам. В данном примере атрибуты width, height, rx, ry, x и y находятся вне пространства имен. Можно изменить пространство имен по умолчанию для конкретного элемента, добавив к элементу атрибут xmlns. Пример <?xml version="1.0"?> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink"> <head><title>Three Namespaces</title></head> <body> <h1 align="center">Эллипс и прямоугольник</h1> <svg xmlns="http://www.w3.org/2000/svg” width="12cm" height="10cm"> <ellipse rx="110" ry="130" /> <rect x="4cm" y="1cm" width="3cm" height="6cm" /> </svg> <p xlink:type="simple" xlink:href="ellipses.html"> Еще об эллипсах </p> <p xlink:type="simple" xlink:href="rectangles.html"> Еще о прямоугольниках </p> <hr/> <p>Последнее изменение 13 мая 2000 года</p> </body> </html> • Пространство имен по умолчанию не применяется к элементам или атрибутам с префиксами, которые в любом случае относятся к тому пространству имен, которому соответствуют их префиксы. • Однако если элемент с префиксом имеет дочерний элемент без префикса, то последний все равно относится к пространству имен по умолчанию. Объявления атрибутов для xmlns • Если пространства имен нужны только для идентификации элементов и атрибутов конкретного XML-приложения, а не для того, чтобы отличать друг от друга разные элементы с одинаковым именем, DTD может присвоить первичным элементам-контейнерам приложения фиксированный атрибут xmlns, благодаря чему все будет относиться к правильному пространству имен без явного использования в документе атрибутов xmlns. – Например, это объявление ATTLIST устанавливает пространство имен по умолчанию http://www.w3.org/2000/ для всех элементов svg: <!ATTLIST svg xmlns CDATA #FIXED "http://www.w3.org/2000/"> – Такое объявление позволяет не писать атрибуты xmlns во всех элементах svg. • Документ не обязан быть действительным, чтобы воспользоваться данный способ задания пространства имен. • Все, что требуется – это чтобы анализатор читал DTD. • Все анализаторы читают внутреннее подмножество DTD и обрабатывают все объявления ATTLIST, найденные в нем. • Лишь немногие не проверяющие анализаторы могут пропустить внешние подмножества DTD, что вызовет путаницу. • В идеальном случае следует использовать анализатор, который может выполнять проверку действительности и потому читает внешнее подмножество DTD, хотя он будет это делать и с отключенной проверкой действительности. Как анализаторы работают с пространствами имен • Анализатор, знающий о пространствах имен, добавляет несколько дополнительных проверок, когда выполняет проверку корректности. • В частности: – он следит за тем, чтобы всем префиксам были поставлены в соответствие URI. – он отвергает документы, в которых встречаются не объявленные префиксы, кроме xml и xmlns, когда те используются в соответствии со спецификациями XML 1.0 и Namespaces in XML. – анализатор отвергает имена элементов и атрибутов, содержащие более одного двоеточия. • В остальном он ведет себя почти так же, как и анализатор, не знающий о пространствах имен. • Другое программное обеспечение, работающее поверх XML анализатора, например процессор XSLT, может по-разному рассматривать элементы в зависимости от того, к какому пространству имен они относятся. • Однако самому XMLанализатору больше ни до чего нет дела, если все требования в отношении корректности и пространств имен соблюдены. Пространства имен и DTD • Пространства имен полностью независимы от DTD и могут использоваться как в действительных (валидных), так и в недействительных (не валидных) документах. • Документ может иметь DTD, но обходиться без пространств имен, или использовать пространства имен, но не иметь DTD. • Можно использовать и пространства имен и DTD или не использовать ни то ни другое. • Пространства имен никак не меняют синтаксис DTD и определение действительности. – Например, DTD действительного документа, в котором есть элемент с именем dc:title, должно включать объявление ELEMENT, соответствующим образом описывающее содержимое элемента dc:title: <!ELEMENT dc:title (#PCDATA)> • Имя элемента в документе должно в точности соответствовать имени элемента в DTD, включая префикс. • DTD не может опустить префикс и просто объявить элемент title. • То же самое касается и атрибутов с префиксами. • Например, если элемент, присутствующий в документе, имеет атрибуты xlink:type и xlink:href, в DTD должны быть объявлены атрибуты xlink:type и xlink:href, а не просто type и href. • И наоборот, если в элементе используется атрибут xmlns для установки пространства имен по умолчанию и пропуска префиксов элементов, имена элементов в DTD также должны объявляться без префиксов. • Валидатор ничего не знает о пространствах имен и не задумывается о них. • Все, что он видит, – это то, что в некоторых элементах и атрибутах встречаются двоеточия; – с его точки зрения, если такие имена объявлены, то они абсолютно допустимы. Ссылки на параметрические сущности и префиксы пространств имен • В DTD требуется объявление имен с префиксами вместо локальных имен или некоторых комбинаций локальных частей и URI пространств имен, что усложняет изменение префиксов в действительных документах. • Проблема состоит в том, что изменение префикса требует также изменения в DTD всех объявлений, где встречается этот префикс. • Облегчить ситуацию можно с помощью ссылок на параметрические сущности. • Во-первых, определите префикс пространства имен и двоеточие, которое отделяет его от локального имени, как параметрические сущности: <!ENTITY % dc-prefix "dc"> <!ENTITY % dc-colon ":"> • Во-вторых, определите уточненные имена как другие ссылки на параметрические сущности: <!ENTITY % dc-title "%dc-prefix;%dc-colon;title"> <!ENTITY % dc-creator "%dc-prefix;%dc-colon;creator"> <!ENTITY % dc-description "%dc-prefix;%dc-colon;description"> <!ENTITY % dc-date "%dc-prefix;%dc-colon;date"> Определение полных имен • Не пропускайте этот шаг и не пытайтесь ссылаться на параметрические сущности dc-prefix и dc-colon непосредственно в объявлениях ELEMENT и ATTLIST. • Из этого ничего не выйдет, так как анализаторы вставляют дополнительные пробелы вокруг заменяемого сущностью текста, находящегося вне текста замены другой сущности. • Затем воспользуйтесь ссылками на сущности вместо уточненных имен во всех объявлениях: <!ELEMENT %dc-title; (#PCDATA)> <!ELEMENT %dc-creator; (#PCDATA)> <!ELEMENT %dc-description; (#PCDATA)> <!ELEMENT %dc-date; (#PCDATA)> <!ELEMENT rdf:Description ((%dc-title; | %dc-creator; | %dc-description; | %dc-date; | )*) > • Теперь в документе, в котором требуется поменять префикс, меняются также и ссылки на параметрические сущности. В некоторых случаях определения можно изменить, непосредственно редактируя DTD. Иначе это можно сделать, переопределив объявления в документе с помощью собственного внутреннего подмножества DTD. Например, чтобы изменить префикс dc на dublin, добавьте гденибудь в DTD перед обычным определением следующее объявление сущности: <!ENTITY % dc-prefix "dublin"> • Если вместо явного указания префиксов вы захотите использовать xmlns, переопределите обе сущности – dc-prefix и dc-colon – на пустые строки: <!ENTITY % dc-prefix ""> <!ENTITY % dc-colon "">