in reply to Re: twig inbuilt methods to sort whole xml tree
in thread twig inbuilt methods to sort whole xml tree

This node falls below the community's threshold of quality. You may see it by logging in.
  • Comment on Re^2: twig inbuilt methods to sort whole xml tree

Replies are listed 'Best First'.
Re^3: twig inbuilt methods to sort whole xml tree
by NetWallah (Canon) on Mar 09, 2010 at 21:01 UTC
    Update: Replaced code with tested , working code.

    This creates an artificial sort order, in order to implement higher priority for specifed elements (Up to 9999 of these).

    #!/bin/perl -w use strict; use XML::Twig; my $twig= XML::Twig->new(pretty_print=>'indented'); $twig->parse(\*DATA); my $root=$twig->root; $root->first_child->sort_children_on_att("type"); #Specify list of items (mainterm) that are forced FIRST in the sort or +der sort_my_kids($root,['mainterm',]); $twig->print; sub sort_my_kids{ my ($me,$OrderTheseFirst) = @_; $me->sort_children( # Use special sort "get_key" sub, to specify artificial sort +order # Generated key is: 4-digit "Specified order", Tag, Value sub{my $el=shift; my $tag=$el->tag; my ($i)= (grep({$tag eq $OrderTheseFirst->[$_]} 0..$#$Ord +erTheseFirst) , 9999); ##Debug# printf " %04d%s\t",$i,$tag; return (sprintf "%04d%s%s",$i,$tag,$el->text_only()); } ); foreach my $kid($me->children){ sort_my_kids($kid,$OrderTheseFirst); # Recursive } }
    Add your own __DATA__ section.

         Theory is when you know something, but it doesn't work.
        Practice is when something works, but you don't know why it works.
        Programmers combine Theory and Practice: Nothing works and they don't know why.         -Anonymous

      Thank you Dear, your coding is fentastic. This solution is working. Even I did my code as below. But my code was specific to elements.Here is my code

      #!/usr/bin/perl use strict; use warnings; use XML::Twig; my (@sortedM, @sortedL); my $i=0; my $twig= new XML::Twig(twig_handlers => { 'enhancement' => sub {$_->first_child- +>sort_children_on_att("type");}, 'descriptor' => \&sortSubEltsHandler, }, pretty_print => 'indented', keep_atts_order => 1, ); $twig->parse(\*DATA); $twig->print; $twig->purge; sub sortSubEltsHandler { my( $t,$elt)= @_; my $root= $t->root; my @mainterms = $root->descendants(q{mainterm}); @sortedM = reverse sort { $a->text cmp $b->text } @mainterms; my @links = $root->descendants(q{link}); @sortedL =reverse sort { $a->text cmp $b->text } @links; $elt->cut_children; foreach my $mainterm (@sortedM) { my $new_elt= XML::Twig::Elt->new($mainterm->name => $mainterm->tex +t); $new_elt->paste($elt); } foreach my $link (@sortedL) { my $new_elt= XML::Twig::Elt->new($link->name => $link->text); $new_elt->paste($elt); } }#end of sortSubEltsHandler __DATA__ <enhancement> <descriptorgroup> <descriptors type="MED" controlled="y"> <descriptor> <mainterm weight="a">plague</mainterm> <mainterm>disease</mainterm> <mainterm>pestilence</mainterm> <link>f</link> <link>C</link> <link>M</link> </descriptor> </descriptors> <descriptors type="DRG" controlled="y"> <descriptor> <mainterm>panadol</mainterm> <mainterm weight="a">zorro</mainterm> <mainterm>xenon</mainterm> <mainterm weight="a">aspirin</mainterm> <link>b</link> <link>P</link> <link>z</link> </descriptor> </descriptors> </descriptorgroup> </enhancement>

        hi NetWallah, I am getting below warning messages more than 200 times. When I ran earlier your code, I did not get this message. now I am getting this. I even added prints in between to check where the variable is not initialized. I could not trace. Use of uninitialized value in string comparison (cmp) at C:/Perl/site/lib/XML/twig.pm line 8820, <DATAFILE> line 9. XML I have tested is as below. Earlier xml was simple, but this is complex. Could u please help me how to solve this error. thank you in advance