2014-11-27 1 views
0

을 사용하는 일부 코드를 내 fatcow 서버에서 사용할 수 없으므로 XML::DOM 대신 사용하려고합니다.펄에 새로운 XML :: DOM :: Document 루트를 만드는 법

XML::DOM::Document 개체의 루트 문서는 어떻게 설정합니까? XML::DOM::Document에는 setDocumentElement 메서드가 없습니다.

다음은 문제의 코드입니다 (XML::XML2JSON). 별표로 표시된 항목을 바꾸는 방법을 알아 내려고합니다.

=head2 obj2dom 

Takes a perl data structure as input. (Must be a hashref.) 
Returns an XML::DOM::Document object. #JMO 

This method expects the object to be in the same format as 
would be returned by the xml2obj method. 

=cut 

sub obj2dom 
{ 
    my ($Self, $Obj) = @_; 

    croak "Object must be a hashref" unless ref($Obj) eq 'HASH'; 

    my $Version = $Obj->{ $Self->{attribute_prefix} . 'version' } || $Obj->{'version'} || '1.0'; 
    my $Encoding = $Obj->{ $Self->{attribute_prefix} . 'encoding' } || $Obj->{'encoding'} || 'UTF-8'; 

    #my $Dom = $XMLPARSER->createDocument($Version, $Encoding); #JMO 
    my $Dom = XML::DOM::Document->new();       #JMO 
    $Dom->setXMLDecl($Dom->createXMLDecl($Version, $Encoding)); #JMO 

    my $GotRoot = 0; 

    #delete @$Obj{ grep { /^$Self->{attribute_prefix}/ } keys %$Obj }; 

    foreach my $Key (keys %$Obj) 
    { 
     $Obj->{$Key} = "" unless defined($Obj->{$Key}); 

     my $RefType = ref($Obj->{$Key}); 
     warn "Value ref type for $Key is: $RefType (value seems to be $Obj->{$Key})" if $Self->{debug}; 

     my $Name = $Key; 

     # replace a "$" in the name with a ":" 
     $Name =~ s/([^^])\$/$1\:/; 

     if ($RefType eq 'HASH') 
     { 
      warn "Creating root element: $Name" if $Self->{debug}; 

      croak "You may only have one root element: $Key" if $GotRoot; 
      $GotRoot = 1; 

      my $Root = $Dom->createElement($Name); 
      $Dom->setDocumentElement($Root);  # ********** 

      $Self->_process_element_hash($Dom, $Root, $Obj->{$Key}); 
     } 
     elsif ($RefType eq 'ARRAY') 
     { 
      croak "You cant have an array of root nodes: $Key"; 
     } 
     elsif (!$RefType) 
     {  
      if ($Obj->{$Key} ne '') 
      { 
       unless ($GotRoot) 
       { 
        my $Root; 
        eval { $Root = $Dom->createElement($Name) }; 
        if ([email protected]) { 
         die "Problem creating root element $Name: [email protected]"; 
        } 
        $Dom->setDocumentElement($Root);  # ********** 
        $Root->appendText($Obj->{$Key}); 
        $GotRoot = 1; 
       } 
      } 
      else 
      { 
       croak "Invalid data for key: $Key"; 
      } 
     } 
     else 
     { 
      warn "unknown reference: $RefType"; 
     } 
    } 

    return $Dom; 
} 
+0

(항상 XML : LibXML을 필요한 경우 libxml2에 설치할 수 있습니다.) – ikegami

+0

C 코드를 설치하지 못하게합니다. ( –

+0

나는 실수라고 생각합니다. 그리고'libxml2'가 C로 쓰여지지 않는다는 문제도 있습니다.) 홈 디렉토리에 설치하는 데 특별한 권한이 필요하지 않습니다. – ikegami

답변

2

XML::DOM::Document 객체는 문서 루트 또는 문서 엔티티를 나타냅니다. 이 부분과 루트 요소은 문서 루트의 유일한 하위이며 XML 문서의 가장 바깥 쪽 요소입니다.

XML::DOM::Document 개체가 있으면 appendChild을 사용하여 추가 한 첫 번째 자식이 루트 요소가됩니다. 당신이 요소 노드가 아닌 다른 것을 추가하려고하면 다음 오류를

XML::DOM::DOMException(Code=3, Name=HIERARCHY_REQUEST_ERR, Message=bad node type) 

을 얻을 것이다 또는 두 개 이상의 노드를 추가하려고하면 당신은 즉

XML::DOM::DOMException(Code=3, Name=HIERARCHY_REQUEST_ERR, Message=document can have only one Element) 

를 볼 것이다, 당신의 setDocumentElement의 가장 가까운 해당 여기이

my $Root = $Dom->createElement($Name); 
$Dom->appendChild($Root); 

처럼, 단순히 appendChild 것은 그 B 예제 프로그램입니다 완전한 XML 문서 트리를 만듭니다. root 태그가있는 요소를 문서 개체에 추가 한 다음 child1child2 태그가있는 두 개의 자식 요소를 만들고 각 요소에 텍스트를 추가 한 다음 루트 요소에 추가합니다.

use strict; 
use 5.010; 
use warnings; 

use XML::DOM; 

my $dom = XML::DOM::Document->new; 
$dom->setXMLDecl($dom->createXMLDecl(qw/ 1.0 UTF-8 /)); 

my $root = $dom->createElement('root'); 
$dom->appendChild($root); 

for my $tag (qw/ child1 child2 /) { 

    my $child = $dom->createElement($tag); 
    $root->appendChild($child); 

    my $text = $dom->createTextNode("Text for $tag"); 
    $child->appendChild($text); 
} 

print $dom->toString; 

출력

<?xml version="1.0" encoding="UTF-8"?> 
<root><child1>Text for child1</child1><child2>Text for child2</child2></root> 

마지막 지점. 식별자의 대문자는 일반적으로 Package::Names과 같이 전역 용으로 예약되어 있습니다. 어휘 범위 변수에는 소문자 영숫자와 밑줄을 사용하는 식별자가 있어야합니다. 그러나이 경우 XML::XML2JSON 모듈 자체가이 규칙을 어기는 것을 알게되었습니다!

+0

위대한 연구와 대답 - 많이 감사합니다! –

+0

위대한 답변! 나는 어휘 범위 변수에 대해 여전히 camelCase를 사용합니다. 아마도 변경하기 어려운 습관 일 수도 있지만, 스타일을 선호하는 다른 사람들도 있습니다. 예를 들어이 토론을 참조하십시오 : http://www.perlmonks.org/? node_id = 990350 –

+0

내 질문에 투표 하시겠습니까? 나는 StackOverflow의 초보자이며 명성을 쌓으려고 노력하고 있습니다 - 고마워요! –