Spec-Zone.ru › SVG

Курс по пространствам имен

В качестве диалекта XML, SVG использует пространства имен. Важно понять концепцию пространств имен и их применение, если вы планируете создавать контент SVG. Пространства имен необходимы для пользовательских агентов, которые поддерживают несколько диалектов XML; браузеры должны быть очень строгими. Потратив время на понимание пространств имен сейчас, вы сэкономите себе головную боль в будущем.

Обзор

Долгосрочной целью различных спецификаций W3C является возможность смешивания различных типов контента на основе XML в одном файле XML или HTML. Например, SVG и MathML могут быть непосредственно включены в научный документ на основе HTML. Возможность смешивания типов контента имеет много преимуществ, но это также потребовало решения очень реальной проблемы.

Естественно, каждый диалект XML определяет значение имен элементов разметки, описанных в его спецификации. Проблема смешивания контента из разных диалектов XML в одном документе заключается в том, что элементы, определенные одним диалектом, могут иметь одинаковые имена с элементами, определенными другим. Например, как HTML, так и SVG имеют элемент <title>. Как пользовательский агент отличает один от другого? Как стили CSS отличают один от другого? Фактически, как пользовательский агент узнает, является ли контент тем, что он знает, а не просто бессмысленным неопределенным пользовательским элементом HTML или файлом XML, содержащим произвольные имена элементов, ему неизвестные?

Вопреки распространённому мнению, ответ на этот вопрос не заключается в «определении из DOCTYPE объявления». DTD никогда не были разработаны с учётом смешанного контента, и предыдущие попытки создания DTD со смешанным контентом сейчас считаются неудачными. XML, а также некоторые диалекты XML (включая SVG и HTML), не требуют DOCTYPE объявления. SVG 1.2 даже не имеет его. То, что DOCTYPE объявления (обычно) соответствуют содержанию файлов с одиночным типом контента, является всего лишь случайностью. DTD предназначены только для проверки, а не для идентификации контента. Любой пользовательский агент, который идентифицирует XML-контент с помощью его DOCTYPE объявления, является ненадежным.

Настоящий ответ на вопрос состоит в том, что XML-контент сообщает пользовательскому агенту, к какому диалекту относятся имена элементов, предоставляя явные «объявления пространств имен».

Объявление пространств имен

Итак, как выглядят эти объявления пространств имен и где они находятся? Вот короткий пример.

svg
<svg xmlns="http://www.w3.org/2000/svg">
  <!-- more tags here -->
</svg>

Объявление пространства имен предоставляется параметром xmlns. Этот параметр указывает, что элемент <svg> и его дочерние элементы принадлежат тому диалекту XML, у которого есть имя пространства имен http://www.w3.org/2000/svg, что, конечно же, SVG. Обратите внимание, что объявление пространства имен предоставляется только один раз для корневого элемента (и подразумевается, если опущено). Объявление определяет стандартное пространство имен, поэтому пользовательский агент знает, что все потомки элемента <svg> также принадлежат тому же пространству имен. Пользовательские агенты проверяют, знают ли они имя пространства имен, чтобы определить, знают ли они, как обработать разметку.

Обратите внимание, что имена пространств имен — это просто строки, поэтому тот факт, что имя пространства имен SVG также выглядит как URI, не имеет значения. URI обычно используются, потому что они уникальны, но цель не в том, чтобы «ссылаться» на что-то. (На самом деле, URI используются так часто, что вместо «имя пространства имен» обычно используется термин «URI пространства имен».)

Переопределение стандартного пространства имен

Если все потомки корневого элемента также определены в стандартном пространстве имен, как вы можете смешать контент из другого пространства имен? Для включения пространства имен SVG в HTML вы включаете <svg>. В XML вы объявляете пространство имен. Вот короткий пример.

xml
<report xmlns="https://www.acme.org/reports">
  <title>Some stats</title>
  <summary>...</summary>
  <statTable xmlns="https://www.acme.org/tables">
    <content>...</content>
    <!-- redeclaring root's default namespace -->
    <summary xmlns="https://www.acme.org/reports">...</summary>
  </statTable>
</report>

В этом примере атрибут xmlns корневого элемента <report> объявляет стандартное пространство имен как https://www.acme.org/reports, или reports. В результате пользовательский агент интерпретирует его и все его дочерние элементы как принадлежащие reports, за исключением элемента <content>, который существует в пространстве имен https://www.acme.org/tables, или tables. Элемент <summary> имеет свой собственный параметр xmlns, а переопределяя пространство имен reports, вы сообщаете пользовательскому агенту, что элемент <summary> и его потомки (если они не переопределяют альтернативное пространство имен) принадлежат reports.

В HTML подразумевается пространство имен http://www.w3.org/1999/xhtml. В SVG — http://www.w3.org/2000/svg. MathML — http://www.w3.org/1998/Math/MathML.

Объявление префиксов пространств имен

Диалекты XML не только определяют свои собственные элементы, но и объявляют свои собственные параметры.

По умолчанию у параметров нет пространства имен. Они уникальны только благодаря тому, что появляются на элементе, имеющем уникальное имя. Однако иногда необходимо определять параметры, чтобы их можно было повторно использовать в нескольких разных элементах и по-прежнему считать одним и тем же параметром, независимо от элемента, с которым они используются. Отличным примером является параметр href, определенный спецификацией XLink. Этот параметр часто используется другими диалектами XML для ссылки на внешние ресурсы. Но как вы сообщаете пользовательскому агенту, к какому диалекту принадлежит параметр, в данном случае XLink? Рассмотрим следующий пример.

xml
<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <script xlink:href="cool-script.js" type="text/javascript" />
</svg>

В этом примере присутствует довольно необычный параметр xmlns:xlink. Как вы можете догадаться из первой части xmlns, это ещё одно объявление пространства имен. Однако вместо определения стандартного пространства имен это объявление пространства имен определяет пространство имен для чего-то, называемого «префиксом пространства имен». В данном случае мы выбрали префикс xlink (вторая часть), поскольку префикс будет использоваться для указания атрибутов, принадлежащих XLink.

Как следует из их названия, префиксы пространств имен используются для добавления префикса к именам параметров и элементов. Это делается путём размещения префикса пространства имен и двоеточия перед именем параметра, как показано на элементе <script> в примере выше. Это сообщает пользовательскому агенту, что конкретный параметр принадлежит пространству имен, назначенному префиксу (XLink), и является параметром, который можно использовать с тем же значением в других элементах.

Обратите внимание, что в XML использование префикса, не связанного с именем пространства имен, является XML-ошибкой. Связь, созданная параметром xmlns:xlink в примере выше, необходима для того, чтобы параметр xlink:href не вызывал ошибку. Этот параметр XLink также часто используется в SVG для элементов <a>, <use> и <image>, среди прочих, поэтому включение объявления XLink в ваши документы — хорошая идея.

Кроме того, полезно знать, что префиксы пространств имен также могут использоваться для имён элементов. Это сообщает пользовательскому агенту, что конкретный элемент (но не его потомки в этот раз!) принадлежит пространству имен, назначенному префиксу. Знание этого поможет избежать путаницы, если вы столкнетесь с разметкой, похожей на пример ниже:

xml
<html
  lang="en"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:svg="http://www.w3.org/2000/svg">
  <body>
    <h1>SVG embedded inline in XHTML</h1>
    <svg:svg width="300px" height="200px">
      <svg:circle cx="150" cy="100" r="50" fill="#ff0000" />
    </svg:svg>
  </body>
</html>

Примечание: Это файл XHTML, а не HTML. Пространства имен XML недействительны в HTML. Чтобы попробовать этот пример, вам нужно сохранить файл как .xhtml.

Обратите внимание, что поскольку префикс пространства имен используется для элемента <svg:svg> и его потомка <svg:circle>, не было необходимости переопределять стандартное пространство имен. Как правило, лучше переопределять стандартное пространство имен, а не добавлять префиксы к многим элементам таким образом.

Скрипты в именованных XML

Пространства имён влияют на разметку и скрипты (и даже на CSS). Если вы пишете скрипты для именованного XML, например, SVG, продолжайте чтение.

Рекомендация DOM Level 1 была создана до выхода рекомендации оригинальных пространств имён в XML; поэтому DOM1 не учитывает пространства имён. Это вызывает проблемы с именованным XML, таким как SVG. Для решения этих проблем DOM Level 2 Core добавил учитывающие пространства имён эквиваленты всех применимых методов DOM Level 1. При написании скриптов для SVG важно использовать методы, учитывающие пространства имён. В таблице ниже перечислены методы DOM1, которые не следует использовать в SVG, а также их эквиваленты DOM2, которые следует использовать вместо них.

DOM1 (не использовать) DOM2 (используйте вместо них!)
createAttribute() createAttributeNS()
createElement() createElementNS()
getAttributeNode() getAttributeNodeNS()
getAttribute() getAttributeNS()
getElementsByTagName() getElementsByTagNameNS() (также добавлено в Element)
getNamedItem() getNamedItemNS()
hasAttribute() hasAttributeNS()
removeAttribute() removeAttributeNS()
removeNamedItem() removeNamedItemNS()
setAttribute() setAttributeNS()
setAttributeNode() setAttributeNodeNS()
setNamedItem() setNamedItemNS()

Первый параметр для всех учитывающих пространства имён методов DOM2 должен быть именем пространства имён (также известным как URI пространства имён) элемента или параметра, о котором идёт речь. Для элементов SVG это http://www.w3.org/2000/svg. Однако обратите внимание: рекомендация Namespaces in XML 1.1 гласит, что имя пространства имён для параметров без префикса не имеет значения. Другими словами, хотя параметры принадлежат пространству имён элемента, вы не используете имя пространства имён тега. Вместо этого вы должны использовать null в качестве имени пространства имён для неопределённых (без префикса) параметров. Таким образом, чтобы создать SVG rect элемент с помощью document.createElementNS(), вы должны написать:

js
document.createElementNS("http://www.w3.org/2000/svg", "rect");

Но чтобы получить значение x параметра в SVG rect элементе, вы должны написать:

js
rect.getAttributeNS(null, "x");

Обратите внимание, что это не относится к параметрам с префиксом пространства имён (параметры, которые не принадлежат тому же диалекту XML, что и элемент). Такие параметры, как xlink:href требуют имени пространства имён, которое было назначено этому префиксу (http://www.w3.org/1999/xlink для XLink). Таким образом, чтобы получить значение параметра xlink:href элемента <a> в SVG, вы бы написали:

js
elt.getAttributeNS("http://www.w3.org/1999/xlink", "href");

Для установки параметров, имеющих пространство имён, рекомендуется (но не обязательно) также включать их префикс во второй параметр, чтобы DOM мог в дальнейшем проще преобразовываться обратно в XML (если, например, вы хотите отправить его обратно на сервер). Например:

js
elt.setAttributeNS(
  "http://www.w3.org/1999/xlink",
  "xlink:href",
  "otherdoc.svg",
);

В качестве последнего примера, вот демонстрация того, как вы могли бы динамически создать <image> элемент с помощью JavaScript:

js
const SVG_NS = "http://www.w3.org/2000/svg";
const XLink_NS = "http://www.w3.org/1999/xlink";
const image = document.createElementNS(SVG_NS, "image");
image.setAttributeNS(null, "width", "100");
image.setAttributeNS(null, "height", "100");
image.setAttributeNS(XLink_NS, "xlink:href", "flower.png");

Заключение

Для SVG, HTML и MathML пространство имён подразумевается и поэтому необязательно. Необходимо объявить пространство имён для XML-файлов. Если вы этого не сделаете, пользовательские агенты не распознают содержимое и отобразят разметку XML или сообщают пользователю об ошибке в XML.

При написании SVG полезно использовать шаблон, который включает все часто используемые объявления пространств имён при создании новых файлов. Если у вас его ещё нет, создайте его, начав с следующего кода:

xml
<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"></svg>

Даже если вы не используете все эти пространства имён в конкретном документе, включение объявлений пространств имён не навредит. Это может сберечь вас от некоторых раздражающих ошибок, если вы добавите содержимое из одного из неиспользуемых пространств имён в более поздний срок.

Полный пример

Для полного примера см. SVG: Справочник по пространствам имён: Пример.

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/SVG/Namespaces_Crash_Course

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API