2013-03-21 3 views
0

신입생 XML::Twig입니다.어떻게 자식 태그를 자식으로 이동할 수 있습니까

하위 태그로 이동 하위 태그가 필요합니다.

어떻게하면됩니까?

notes 태그와 일치하면 하위 태그가있는 상위 태그가 섹션 이전으로 이동합니다.

내 XML은 다음과 같습니다

<book> 
    <sec> 
    <p>The indicated something</p> 
    <p>The something</p> 
    </sec> 
    <sec> 
    <notes>note</notes> 
    <p>text</p> 
    </sec> 

    <sec> 
    <p>The indicated</p> 
    <p>The something</p> 
    </sec> 
    <sec> 
    <notes>note</notes> 
    <p>text1</p> 
    </sec> 

</book> 

내가 시도 :

use XML::Twig; 

open(my $output, ">output.xml") || die "can't open the output.xml$!\n"; 

my $story_file = XML::Twig->new(
    keep_encoding => 1, 
    twig_handlers => { 'book' => \&book, }, 
    pretty_print => 'indented', 
); 
$story_file->parse("sample.xml"); 
$story_file->print($output); 
$story_file->purge; 

sub book { 
    my ($stroy_file, $book) = @_; 
    my @sub_elmt = $book->children; 
    Get_children(\@sub_elmt) if ($#sub_elmt >= 0); 
} 

sub Get_children { 
    my ($ref) = @_; 
    foreach my $tagg (@$ref) { 
     my @children = $tagg->children; 
     my $tagName = $tagg->name; 
     if ($tagName =~ /^sec$/) { 
      my $f = $tagg->first_child; 
      if ($f->name =~ /^notes$/) { 
       $tagg->move('last_child', $tagg); 
      } 
     } 
     Get_children(\@children) if ($#children >= 0); 
    } 
} 
그것은 작동하지 않을 수

, 나는이 어떻게 할 수 있습니까? 나는이 작업을 수행하는 방법

<book> 
    <sec> 
    <p>The indicated something</p> 
    <p>The something</p> 
    <sec> 
     <notes>note</notes> 
     <p>text</p> 
    </sec> 
    </sec> 
    <sec> 
    <p>The indicated</p> 
    <p>The something</p> 
    <sec> 
     <notes>note</notes> 
     <p>text1</p> 
    </sec> 
    </sec> 
</book> 

:

은이 같은 출력을해야합니까?

+0

구조를 보여 제대로 프로그램을 들여하십시오. 그대로 읽을 수 없습니다. – Borodin

답변

1

XML::Twig가 0123을 사용하여 조각에 의해 매우 큰 XML 문서 조각을 처리하기위한 매우 유용 할 수있는 방법을 보여줍니다,하지만 당신은 을 사용하지 마십시오. 완전한 XML 문서 트리를 만들고 다른 대부분의 XML 모듈처럼 트리를 조작하고 인쇄 할 수 있습니다.

이 프로그램은 sample.xml에서 전체 문서를 읽고 sec 요소 안에있는 모든 notes 요소를 검색합니다. sec 요소를 포함하는 요소는 parent을 사용하여 찾았으며 을 사용하여 이전에 sec 요소 (이 요소를 삽입 할 요소)를 찾았습니다. 그 다음 movesec 요소를 앞의 sec의 마지막 자식으로 재배치하는 데 사용됩니다.

use strict; 
use warnings; 

use XML::Twig; 

my $twig = XML::Twig->new; 
$twig->parsefile('sample.xml'); 

for my $notes ($twig->findnodes('//sec/notes')) { 
    my $sec = $notes->parent; 
    my $prev_sec = $sec->prev_sibling('sec'); 
    $sec->move(last_child => $prev_sec); 
} 

$twig->print_to_file('output.xml', pretty_print => 'indented'); 

출력

<book> 
    <sec> 
    <p>The indicated something</p> 
    <p>The something</p> 
    <sec> 
     <notes>note</notes> 
     <p>text</p> 
    </sec> 
    </sec> 
    <sec> 
    <p>The indicated</p> 
    <p>The something</p> 
    <sec> 
     <notes>note</notes> 
     <p>text1</p> 
    </sec> 
    </sec> 
</book> 
0

XML과 Perl 스크립트에서 일부 오타가 있습니다. NB. &을 수정하여 XML 예제를 정리했습니다 (참고 태그 참조).

귀하의 주요 문제는 (! 자체 즉.) $tagg->move$tagg로 이동한다는 것입니다 그래서이 작동하지 않습니다 :(아래

내 단순화 된 버전이 필요한 것을 수행하는 것입니다 (즉,이. 그것은 book/sec을 볼 때 첫 아이 notes와 태그는 다음이 sec가) 이전 sec 끝으로 이동하고 ->move 작품.

use strict; 
use warnings; 
use XML::Twig; 

my $book_sec = do { 
    my $last_sec; 
    sub { 
     my ($twig, $sec) = @_; 

     # if <sec> has first child <notes> then this needs 
     # to be moved to end of previous <sec> 

     $sec->move('last_child', $last_sec) 
      if $sec->first_child('notes') && $last_sec; 

     $last_sec = $sec; # cache that last <sec> 
    }; 
}; 

XML::Twig->new(
    twig_handlers => { 'book/sec' => $book_sec }, 
    pretty_print => 'indented', 
)->parsefile('sample.xml')->print_to_file('output.xml'); 
+0

폐쇄! 우아한! – Borodin

관련 문제