2010-03-01 69 views
2

我相信這個問題might have been previously attempted in 2006在不同的網站上。但是,我現在的XML/RDF編寫器(XML::LibXML 1.70)以xmlns屬性的形式輸出元素名稱空間。這將排除使用非名稱空間感知解析器的人員,他們只爲foaf:Person做一個look_down。我想知道是否有人知道在perl中實現這一目的的簡單方法,首先是XML::LibXML。或通過不同的方式。使用perl的XML :: LibXML你如何使用XML前綴而不是xmlns屬性?

節點是這樣的:

<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> 

任何想法?我相信這兩種方法在技術上都是正確的,但我寧願不依靠其他人知道這一點。我昨天自己並不知道。

+0

我甚至不確定這是否正確。我完全糊塗在這裏。 – 2010-03-01 23:48:24

+0

我和埃文在一起。你錯了 - 你試圖把一個有效的FOAF文件變成一些沒有的文件。使用非名稱空間感知的「XML解析器」的人不是你的問題,如果是這樣,你不應該試圖通過在你的最後破壞事情來解決它。 – reinierpost 2010-03-02 17:58:06

+0

你是和'Evan誰提出這個問題,或者Evan是誰發表了第一個評論?我不確定你認爲誰是'錯誤',但是有時(有時)明智的理由要嚴格控制名稱空間聲明。這可以通過XML :: LibXML的DOM綁定來實現。據我所知,通過行使這種控制,沒有任何東西被打破。 – 2010-03-02 18:24:55

回答

4

簡短的回答是,如果您已經聲明瞭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 Namespaces存在允許多個詞彙表在同一個XML文檔中一起使用。爲了實現這一點,引入了namespaceURI(nsURI)的概念,並指出了哪種nsURI與XML文檔中的哪些元素和屬性相關的機制被改進爲XML。爲此,使用了以下事實:允許使用特殊屬性名稱(xmlns)的屬性名稱以'xml'are reserved開頭,沒有碰撞風險。

總體思路是,可以將XML文檔中使用的每個詞彙表與唯一的nsURI(將其視爲不透明字符串)相關聯。 XHTML詞彙表中的頭元素由{'http://www.w3.org/1999/xhtml':'head'}完全定義,並且這與(假設的)解剖結構-ML {'my-up-URI':'head 「}。問題是如何將nsURI(s)嵌入到XML文檔中,以及如何將這些文檔鏈接到元素名稱。

使nsURI和元素名稱之間的鏈接的一種方法是將xmlns屬性添加到元素。例如:

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

說'姓名'位於'http://xmlns.com/foaf/0.1/'命名空間中。命名空間聲明由孩子繼承,所以「年齡」是在同一個名字:

<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文檔被重複處理時,名稱空間前綴可能會在奇怪的位置發生更改。大多數解析器都可以識別名稱空間。

+0

謝謝。我非常感謝你的回答。 – 2010-03-02 17:24:30

相關問題