2012-05-30 3 views
5

XML :XPath 표현식() 반환 빈 노드 목록

<zoo xmlns="http://www.zoo.com" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://www.zoo.com employee.xsd"> 

<area id="1" posizione="nord" nome="scimmie"> 
    <animale> 
     <nome>Gigi</nome> 
     <sesso>Male</sesso> 
     <eta>3</eta> 
    </animale> 

    <animale> 
     <nome>Gigia</nome> 
     <sesso>Female</sesso> 
     <eta>2</eta> 
    </animale> 
</area> 

<area id="2" posizione="nord" nome="giraffe"> 
    <animale> 
     <nome>Giro</nome> 
     <sesso>Male</sesso> 
     <eta>6</eta> 
    </animale> 

    <animale> 
     <nome>Gira</nome> 
     <sesso>Female</sesso> 
     <eta>5</eta> 
    </animale> 
</area> 
</zoo> 

코드 :

my $parser = XML::LibXML->new; 
my $doc = $parser->parse_file("../xml/animals.xml"); 
my $root = $doc->getDocumentElement(); 

my $new_animal = $doc->createElement("animale"); 

my $name_element = $doc->createElement("nome"); 
$name_element->appendTextNode($name); 

my $gender_element = $doc->createElement("sesso"); 
$gender_element->appendTextNode($gender); 

my $age_element = $doc->createElement("eta"); 
$age_element->appendTextNode($age); 

$new_animal->appendChild($name_element); 
$new_animal->appendChild($gender_element); 
$new_animal->appendChild($age_element); 

my $area_element = $root -> findnodes("//area[\@id=$area]")->get_node(1); 

$area_element->appendChild($new_animal); 

$ 영역은 영역의 ID입니다 (지금은 보통 1 내가 테스트하고있어 것을)

내 목적은 새로운 동물을 만들고 적절한 동물에 추가하는 것입니다.

그러나 나는 istructio $의 area_element이 미확정 때문에 findnodes 항상 빈 노드 목록을 반환하기 때문에 N

my $area_element = $root -> findnodes("//area[\@id=$area]")->get_node(1); 

이 작동하지 않습니다 (크기 (인쇄 확인)).

문제는 findnodes 내부의 xpath 표현이라고 생각하지만 잘못된 것이 무엇인지 이해할 수 없으며 다른 라이브러리 (XML :: XPath)와 동일한 표현식을 사용하며 작동합니다.

무엇이 잘못 되었나요?

답변

4

XML에서 디프레션 네임 스페이스의 URI는 http://www.zoo.com이므로 XPath 식에서 노드를 선택해야합니다.

이 방법은이 네임 스페이스에 이름을 할당하는 XML::LibXML::XPathContext 개체를 선언하는 것입니다. 그런 다음이 이름을 XPath 표현식에 사용하여 노드에 액세스 할 수 있습니다.

당신이

my $xpc = XML::LibXML::XPathContext->new; 
$xpc->registerNs('zoo', 'http://www.zoo.com'); 

를 작성하는 경우 당신은 이제 XML의 기본 네임 스페이스가 zoo 명명되는 상황이있다. 지금 당신은

my $area_element = $xpc->findnodes("//zoo:area[\@id=$area]", $doc)->get_node(1); 

을 쓸 수 있으며 정확한 <area> 요소를 찾을 수 있습니다.

+0

코드를 사용해 보았지만 다음과 같이 나타납니다. ---------- 소프트웨어 오류 : XPathContext : /Users/toyo/Sites/zoo/cgi-bin/_nuovo_animale.cgi 줄의 현재 노드가 손실되었습니다. 76 --------- line 76은 다음과 같습니다. my $ area_element = $ xpc -> findnodes ("// zoo : area [\ @ id = $ area]") -> get_node (1); – qwertoyo

+0

@qwertoyo, 이것은 새로운 문제이며 여기에서 논의 할 공간이 없습니다. 새로운 질문을하고 문제를 설명하는 데 필요한 최소 실행 코드를 제공하십시오. – ikegami

+0

@qwertoyo, 간단한 시도 :'my ($ area_element) = $ xpc-> findnodes ("// 동물원 : 지역 [\ @ 아이디 = $ 지역]", $ 의사), ' – ikegami

-2

네임 스페이스 선언이 잘못되었으므로 <zoo xmlns:zoo="http://www.zoo.com" 또는 그와 비슷한 내용이 있어야합니다.

+0

네임 스페이스 ID가없는'xmlns = "http://www.zoo.com"은 단순히 * 기본 * 네임 스페이스 즉 접두사가없는 모든 요소의 네임 스페이스를 바인딩합니다. 기본 네임 스페이스에 대한 정의가 없다면 마치'xmlns = ""'선언이 사용 된 것과 같습니다. – Borodin

+0

''그리고''는 맞고 동등합니다 (아이들이 접두사의 부족/존재를 모방한다고 가정 할 때). ''에 정의 된 네임 스페이스는 결코 사용되지 않으므로 조언이 잘못되었습니다. – ikegami

+0

답이 잘못되었습니다. 네임 스페이스 선언에는 아무런 문제가 없습니다. 하향 투표. –