2010-03-01 28 views
2

我想用FOAF和Perl做一些事情。我對目前的解決方案不滿意,我想推出自己的解決方案。請不要參考XML::LibXML以外的任何模塊。使用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重新創建此片段。不過,我不幸陷入了第一線。這只是集中在第一行:

我讀這是

  1. 元素RDF,在命名空間rdf聲明
    1. 屬性rdf在命名空間xmlns與價值http://www.w3.org/1999/02/22-rdf-syntax-ns#
    2. 屬性rdfs在命名空間xmlns價值http://www.w3.org/2000/01/rdf-schema#
    3. 屬性foaf在命名空間xmlns與命名空間xmlnshttp://xmlns.com/foaf/0.1/
    4. 屬性admin與價值http://webns.net/mvcb/

首先你需要一個元素rdf:RDF,這似乎是棘手。讀documentationXML::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::DocumentcreateAttributeNS但它沒有工作,要麼:

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'); 

其實我得到這個錯誤:‘不能對屬性創建一個新的命名空間’這似乎與方法名稱暗含的含義相矛盾,並與文檔描述相關:「創建綁定到名稱空間的屬性」。

所以,我認爲,我不能createattributeNS,也許我可以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 attribute!」。所以我回顧了一些測試,發現這需要一個屬性key-value而不是名稱空間聲明來做我想做的事情。這不是我想要的。

下面是一些可能的組合和輸出:

$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提供的與DOM的快速XML創建。

+0

由於Evan明確地禁止了它,所以我不會提到任何其他模塊,但是我會注意到,在使用RDF時,特定於RDF的模塊會更好,特別是因爲XML是RDF的糟糕序列化。 – MkV 2010-03-01 22:41:16

+0

我正在爲FOAF做這個,如果你知道它比XML更廣泛的採用,那就去做吧!如果不是,我想要做的就是創建一個模型,它會在TT和Catalyst中爲您提供FOAF和HCARD模板和渲染。更具體地說,創建社交網絡類型的東西,並迎合可以利用它的爬蟲(谷歌地圖) – 2010-03-01 23:20:52

回答

6

從內存(和編輯的正確性),你做這樣的:

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/', '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/', 'name'); 
$node2->appendTextNode('Evan Carroll'); 
$node->appendChild($node2); 
print $doc->toString; 

也就是說,你總是需要使用的命名空間的URI,並添加命名空間聲明的根節點(這是你指定命名空間前綴的唯一地方 - 我認爲如果你不提供它們,libxml將會創建它自己的前綴)。從維護的角度來看,將這些放在一些變量中顯然是明智的。

只要您不需要內存中的DOM可以識別名稱空間,您的最終(非名稱空間)版本就可以工作。這是因爲Level 1 DOM不知道名稱空間:您可以將名稱空間視爲普通屬性,並且文檔仍然可以正常形成(但可能不是名稱空間格式良好)。

這適用於某一點,但命名空間前綴不是給定的。討論這個is elsewhere

+0

這是一篇很棒的文章,但它對我來說根本不編譯?有任何想法嗎? – 2010-03-01 21:15:47

+0

@Evan:什麼部分不編譯? – Ether 2010-03-01 21:31:01

+0

大概我的記憶是錯誤的。任何有用的錯誤消息? – 2010-03-01 21:31:27

相關問題