2010-03-01 88 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

相关问题