Короткий ответ: если у вас уже есть namespaceURI и объявленный префикс, вы можете указать полное имя (то есть префикс: localName) в качестве имени элемента, и это позволит XML :: LibXML избежать повторного разделения пространства имен. Таким образом, изменение кода из последнего вопроса дает следующее, которое использует нужные префиксы пространства имен:
#! /usr/bin/perl
use warnings;
use strict;
use XML::LibXML;
my $doc = XML::LibXML::Document->new( '1.0', 'UTF-8' );
my $foaf = $doc->createElementNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'RDF' );
$doc->setDocumentElement( $foaf );
$foaf->setNamespace( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' , 'rdf', 1 );
$foaf->setNamespace( 'http://www.w3.org/2000/01/rdf-schema#' , 'rdfs', 0 );
$foaf->setNamespace( 'http://xmlns.com/foaf/0.1/' , 'foaf', 0 );
$foaf->setNamespace( 'http://webns.net/mvcb/' , 'admin', 0 );
my $node = $doc->createElementNS( 'http://xmlns.com/foaf/0.1/', 'foaf:Person');
$foaf->appendChild($node);
$node->setAttributeNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'ID', 'me');
my $node2 = $doc->createElementNS( 'http://xmlns.com/foaf/0.1/', 'foaf:name');
$node2->appendTextNode('Evan Carroll');
$node->appendChild($node2);
print $doc->toString;
Возможно, стоит попытаться проанализировать, что происходит. Пространства имен XML существуют, чтобы позволить нескольким словарям использоваться вместе в одном документе XML. Для достижения этой цели вводится концепция namespaceURI (nsURI) и механизм указания того, какой nsURI относится к каким элементам и атрибутам в XML-документе, встраивается в XML. Для этого используется тот факт, что имена атрибутов, начинающиеся с «xml» , зарезервированы , что позволяет использовать специальное имя атрибута (xmlns) без риска столкновения.
Общая идея заключается в том, что можно связать каждый словарь, используемый в документе XML, с уникальным nsURI (который рассматривается как непрозрачная строка). Элемент head в словаре XHTML полностью определяется {{http://www.w3.org/1999/xhtml':'head'},, и это явно отличается от заголовка в (гипотетической) анатомии-ML {'my-made-up-URI': 'head'} , Вопрос заключается в том, как встроить nsURI в документ XML и как связать их с именами элементов.
Одним из способов установить связь между nsURI и именем элемента является добавление атрибута xmlns к элементу. Например:
<name xmlns="http://xmlns.com/foaf/0.1/">Evan Carroll</name>
говорит, что имя находится в пространстве имен http://xmlns.com/foaf/0.1/'. Объявления пространства имен наследуются детьми, поэтому «age» находится в том же пространстве имен:
<name xmlns="http://xmlns.com/foaf/0.1/">Evan Carroll<age years='21'/></name>
Это может хорошо работать и быть достаточно компактным. Тем не менее, это не работает для атрибутов и может стать беспорядочным, если многим узлам-братьям необходимо изменить пространство имен от их общего родителя. Для решения обеих этих проблем введено NamespacePrefix (nsPrefix). Это дает двоеточие особый смысл. Идея состоит в том, чтобы связать nsURI со строкой, которая используется в текущем документе. Это не имеет какого-либо особого значения вне документа и не должно указываться в словаре (но иногда это обсуждение в другом месте). Особенно часто все nsURI объявляются в корневом элементе. Синтаксис должен объявить пространство имен следующим образом:
xmlns:prefix="http://xmlns.com/foaf/0.1/"
и используйте его в именах атрибутов и элементов, добавив nsPrefix к имени:
<prefix:name prefix:attribute='value'/>
Поскольку точное значение nsPrefixes не должно иметь значения, API, как правило, не облегчают доступ к ним / их настройку (хороший пример - Xpath). Наличие пространств имен приводит к некоторым ограничениям в документе, которые следует рассматривать как ошибки, например, использование префикса, который не определен. Но такой документ может быть правильно сформирован в соответствии со спецификацией XML (помните, что пространства имен модифицированы). Вы можете охарактеризовать такой документ как «неправильно сформированное пространство имен».
Анализ документа, использующего пространства имен, с анализатором, который ничего не знает о пространствах имен, очевидно, проще, если вы знаете заранее используемые префиксы пространства имен. Но это довольно хрупкое решение, так как префиксы пространства имен могут изменяться в нечетных местах, поскольку документ XML неоднократно обрабатывается. Большинство парсеров осведомлены о пространстве имен.