2010-03-01 1 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 사용 xmlns 특성이 아닌 XML 접두사를 어떻게 사용합니까?

노드 :

<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

이 정보가 정확한지 확신 할 수 없습니다. 나는 여기서 완전히 혼란스러워. –

+0

나는 Evan과 함께있다. 당신은 틀렸어. 유효한 FOAF 문서를 그렇지 않은 것으로 바꾼다. 비 네임 스페이스를 인식하는 "XML 파서"를 사용하는 사람들은 문제가되지 않습니다. 그렇다면 마지막 단점을 해소하여이를 고쳐서는 안됩니다. – reinierpost

+0

첫 번째 의견을 남긴 Evan 또는 질문을 한 Evan과 '함께하고 있습니까?' 네가 '틀린'사람이라고 생각하는지 모르겠지만 네임 스페이스 선언을 엄격하게 제어 할 수있는 합리적인 이유가있다. XML :: LibXML의 DOM 바인딩을 사용하면이 작업을 수행 할 수 있습니다. 내가 볼 수있는 한,이 통제를 행사하면 '고장'은 없습니다. –

답변

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) 개념이 도입되었으며 XML 문서의 어떤 요소와 속성과 관련된 nsURI가 XML에 추가되는지 나타내는 메커니즘이 도입되었습니다. 이렇게하려면 'xml'을 시작하는 속성 이름이 특수 속성 이름 (xmlns)이 충돌을 일으키지 않고 사용되도록 허용하는 are reserved이라는 사실을 사용해야합니다.

일반적인 생각은 XML 문서에 사용 된 각 어휘를 고유 한 nsURI (불투명 한 문자열로 처리됨)와 연결할 수 있다는 것입니다. XHTML 어휘의 head 요소는 { 'http://www.w3.org/1999/xhtml': 'head'}로 완전히 정의되어 있으며 이는 가상의 해부학 ML ('my-made-up-URI': '머리 '}. 문제는 XML 문서에 nsURI를 삽입하는 방법과이를 요소 이름에 연결하는 방법입니다.

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를 앞에 붙이는 속성과 요소 이름에서 사용 : nsPrefixes의 정확한 값은 문제가 안되기 때문에

<prefix:name prefix:attribute='value'/> 

구문은 따라서 네임 스페이스를 선언하는 것입니다 API는 일반적으로 액세스/설정이 매우 쉽지 않습니다 (Xpath는 좋은 예입니다). 네임 스페이스를 사용하면 문서에서 오류로 취급해야하는 제약이 생기고 정의되지 않은 접두사를 사용하는 것이 예입니다. 그러나 이러한 문서는 XML 사양에 따라 잘 형성 될 수 있습니다 (네임 스페이스가 개조 된 것을 기억하십시오). 네임 스페이스가 정형화되지 않은 문서를 설명 할 수 있습니다.

사전에 사용 된 네임 스페이스 접두사를 알고있는 경우 네임 스페이스에 대해 알지 못하는 파서를 사용하여 네임 스페이스를 사용하는 문서를 파싱하는 것이 분명 쉽습니다. 그러나 이것은 XML 문서가 반복적으로 처리 될 때 네임 스페이스 접두사가 이상한 곳에서 바뀔 수 있기 때문에 상당히 문제가됩니다. 대부분의 파서는 네임 스페이스를 인식합니다.

+0

감사합니다. 나는 정말로 당신의 대답에 감사드립니다. –

관련 문제