Maybe you should step away and rethink your algorithm. Maybe it would be better to create the tree structure of sections first and then export that as XML. As your read the sections from the CSV you can keep a hash (or array if the nodeIds are positive integers and are not too sparse) of references to the individual sections and add the children easily. Without having to search for them using XPath or any other advanced thing:
my @columns = qw(parentNodeId nodeId level canode label);
my $CSV = <<'*END*';
0,1,0,blah,bloh
1,2,1,foo,faaa
1,3,1,bar,barrar
2,4,2,baz,bazbaz
2,5,2,aaa,aaaaa
3,6,2,bbb,bbbbbbab
4,7,3,zzz,zzzzz
*END*
my (%sections, $root);
my @navmod = split /\n/, $CSV;
foreach my $line (@navmod) {
my %current;
@current{@columns} = split /,/, $line;
delete $current{level};
my $nodeId = $current{nodeId};
$sections{$nodeId} = \%current;
my $parentNodeId = delete $current{parentNodeId};
if ($parentNodeId) {
push @{$sections{$parentNodeId}{section}}, \%current;
} else {
$root = \%current;
}
}
use XML::Rules;
my $parser = XML::Rules->new( rules => []);
print $parser->ToXML(section => $root, 0, ' ');
And if your CSV is already sorted enough so that no node is referenced sooner than it's defined you do not have to read the whole CSV into an array and sort it more, but may read it line by line and build the tree.
It's actually fairly easy to tweak the code to work even if sections do get referenced before they are defined:
my @columns = qw(parentNodeId nodeId level canode label);
my (%sections, $root);
while (my $line = <DATA>) {
chomp($line);
my %current;
@current{@columns} = split /,/, $line;
delete $current{level};
my $nodeId = $current{nodeId};
my $parentNodeId = delete $current{parentNodeId};
if ($sections{$nodeId}) {
%{$sections{$nodeId}} = ( %current, %{$sections{$nodeId}});
} else {
$sections{$nodeId} = \%current;
}
if ($parentNodeId) {
push @{$sections{$parentNodeId}{section}}, $sections{$nodeId};
} else {
$root = $sections{$nodeId};
}
}
use XML::Rules;
my $parser = XML::Rules->new( rules => []);
print $parser->ToXML(section => $root, 0, ' ');
__DATA__
3,6,2,bbb,bbbbbbab
1,2,1,foo,faaa
2,4,2,baz,bazbaz
2,5,2,aaa,aaaaa
1,3,1,bar,barrar
4,7,3,zzz,zzzzz
0,1,0,blah,bloh
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.