Я пытаюсь сделать кое-что с FOAF и Perl. Я недоволен текущими решениями и хочу накатить свои. Пожалуйста, не ссылайтесь ни на один модуль, кроме XML::LibXML
.
Для справки приведен фрагмент из файла FOAF
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:admin="http://webns.net/mvcb/">
<foaf:Person rdf:ID="me">
<foaf:name>Evan Carroll</foaf:name>
....
Теперь, за исключением пробелов, я пытаюсь воссоздать это с помощью XML::LibXML
. Однако, к сожалению, я застрял на самой первой строчке. Это просто фокусируется на первой строке:
Я прочитал это, чтобы быть
- элемент
RDF
, в пространстве имен rdf
объявляет
- атрибут
rdf
в пространстве имен xmlns
со значением http://www.w3.org/1999/02/22-rdf-syntax-ns#
- атрибут
rdfs
в пространстве имен xmlns
со значением http://www.w3.org/2000/01/rdf-schema#
- атрибут
foaf
в пространстве имен xmlns
со значением http://xmlns.com/foaf/0.1/
- атрибут
admin
в пространстве имен xmlns
со значением http://webns.net/mvcb/
Во-первых, вам нужен элемент rdf:RDF
, это кажется хитрым. Читая документацию для XML::LibXML::Document
Я нашел createElementNS()
, но, похоже, это не делает то, что я хочу:
use XML::LibXML;
my $doc = XML::LibXML::Document->new( '1.0', 'UTF-8' );
my $foaf = $doc->createElementNS( 'RDF', 'rdf' );
print $foaf->toString; # prints <rdf xmlns="RDF"/>
Теперь я пытаюсь createElement('rdf:RDF')
, и это работает! Я получил корневой элемент rdf:RDF
. Это то, как мы должны создавать корневые элементы? Я просто читаю XML неправильно?
Теперь мне нужно создать атрибуты (объявления схемы). Я пробовал плохо документированные XML::LibXML::Document
createAttributeNS
, но они тоже не работали:
my $doc = XML::LibXML::Document->new( '1.0', 'UTF-8' );
my $foaf = $doc->createElement( 'rdf:RDF' );
$doc->createAttributeNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf' );
На самом деле я получаю эту ошибку: "не могу создать новое пространство имен для атрибута!" , что кажется противоречащим тому, что подразумевает название метода, и его описанию в документации: «Создает атрибут, связанный с пространством имен.»
Итак, я думаю, хорошо, я не могу create
и attributeNS
, может быть, тогда я смогу set
и attributeNS
. И на этот раз я перехожу к следующему документированному методу XML::LibXML::Element
, который выглядит применимым: setAttributeNS
.
my $doc = XML::LibXML::Document->new( '1.0', 'UTF-8' );
my $foaf = $doc->createElement( 'rdf:RDF' );
$foaf->setAttributeNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf' );
На этот раз я получаю другую ошибку: "атрибут bad ns!" . Поэтому я проверяю некоторые из тестов и нахожу, что для этого требуется значение ключа атрибута, отличное от объявления пространства имен, чтобы делать то, что я хочу ... Что не то, что я хочу.
Вот несколько возможных комбинаций и выходов:
$foaf->setAttributeNS( http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:', undef );
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rdf:=""/>
$foaf->setAttributeNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:foo', 'bar' );
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rdf:foo="bar"/>
Кажется, ни один из * NS-методов не работает, хотя я знаю, что они связаны с пространствами имен XML. Наконец, я пробую не-NS версию:
my $doc = XML::LibXML::Document->new( '1.0', 'UTF-8' );
my $foaf = $doc->createElement( 'rdf:RDF' );
$foaf->setAttribute( 'xmlns:rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' );
print $foaf->toString; # <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"/>
У меня такое ужасное чувство, что я не правильно делаю . Я сделал это правильно? Как добавить дочерний элемент с DOM (не используя appendTextChild
)?
Все это XML::LibXML
очень плохо документировано, но, похоже, лучшее, что может предложить Perl для быстрого создания XML с DOM.