2

この質問は、2006年に別のサイトで以前に試みられた可能性があると思います。しかし、私の現在のXML / RDFライター(XML::LibXML1.70)は、要素の名前空間をxmlns属性の形式で出力します。これにより、名前空間を認識しないパーサーを使用していて、のlook_downを実行する人は除外されfoaf:Personます。最初に、これを達成するためのperlの簡単な方法を誰かが知っているかどうか疑問に思いXML::LibXMLます。または別の方法で。

このようなノード:

  <Person xmlns="http://xmlns.com/foaf/0.1/" rdf:ID="me"/>

この:

  <name xmlns="http://xmlns.com/foaf/0.1/">Evan Carroll</name>

本当に次のようになります:

  <foaf:Person rdf:ID="me"/>
  <foaf:name>Evan Carroll</name>

何か案は?どちらにしても技術的には正しいと思いますが、これを知っている他の人に頼りたくはありません。昨日は知らなかった。

4

1 に答える 1

5

簡単に言うと、namespaceURIとプレフィックスがすでに宣言されている場合は、要素名として修飾名(つまり、prefix: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(不透明な文字列として扱われる)にリンクすることが可能であるということです。XHTMLボキャブラリーのhead要素は{' http://www.w3.org/1999/xhtml':'head '}によって完全に定義されており、これは(仮想の)解剖学的構造のheadとは明らかに異なります-ML { 'my-made-up-URI':'head'}。問題は、nsURIをXMLドキュメントに埋め込む方法と、これらを要素名にリンクする方法です。

nsURIと要素名の間にリンクを作成する1つの方法は、要素にxmlns属性を追加することです。例えば:

<name xmlns="http://xmlns.com/foaf/0.1/">Evan Carroll</name>

'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ドキュメントが繰り返し処理されると、名前空間プレフィックスが奇妙な場所で変更される可能性があるため、これは非常に脆弱なソリューションです。ほとんどのパーサーは名前空間を認識しています。

于 2010-03-02T10:14:57.533 に答える