2

例如,输入是

    root
    ^^aa
    ^^^^bb
    ^^cc
    ^^dd

两个 ^^ 代表一个缩进,因此 aa 是 root 的孩子,bb 是 aa 的孩子。
aa,cc 和 dd 是兄弟,他们都是 root 的孩子。

输出是一个 xml 文件,它的内容是

<?xml version='1.0'?>
<dir name="root">
  <dir name="aa">
    <dir name="bb" />
  </dir>
  <dir name="cc" />
  <dir name="dd" />
</dir>

但我找不到合适的 perl 脚本来解决这个问题。
所以寻求帮助,非常感谢。

4

2 回答 2

1

您也可以使用XML::LibXML来完成此任务。您只需要通过这种方式了解上一个级别和上一个元素:

use XML::LibXML;

my $doc = XML::LibXML::Document->new();
my $previousLevel = 0;
my $previousElement;

foreach my $line (@data) {
    if($line =~ m/^(\^*)(.+)$/) {
        my $level = (length $1) / 2;
        my $name = $2;

        my $dir = $doc->createElement('dir');
        $dir->setAttribute('name', $name);

        if($level == 0) {
            $doc->setDocumentElement($dir);
        }
        elsif($level > $previousLevel) {
            $previousElement->addChild($dir);
        }
        elsif($level < $previousLevel) {
            $previousElement = $previousElement->parentNode()
               for ($level .. $previousLevel -1);
            $previousElement->addSibling($dir);
        }
        elsif($level == $previousLevel) {
            $previousElement->addSibling($dir);
        }

        $previousElement = $dir;
        $previousLevel = $level;
    }
}

print $doc->toString(2);
于 2012-06-29T20:06:50.883 回答
-1

通过比较当前节点的深度和前一个节点的深度,您可以获得所需的所有信息。

my $last_depth = -1;
while (@input) {
   my $name = shift(@input);

   my $depth = 0;
   ++$depth while $name =~ s/^\^\^//;

   while ($depth <= $last_depth) {
      end_dir($last_depth);
      --$last_depth;
   }

   die if $depth != $last_depth + 1;

   start_dir($depth, $name);
   ++$last_depth;
}

while ($last_depth > -1) {
   end_dir($last_depth);
   --$last_depth;
}

程序的其余部分

my %escapes = (
   '&' => '&amp;',
   '<' => '&lt;',
   '>' => '&gt;',
   '"' => '&quot;',
   "'" => '&apos;',
);

sub text_to_xml {
   my ($s) = @_;
   $s =~ s/([&<>'"])/$escapes{$1}/g;
   return $s;
}

sub start_dir { print(('  ' x $_[0]) . qq{<dir name="}.text_to_xml($_[1]).qq{">\n}); }
sub end_dir   { print(('  ' x $_[0]) . qq{</dir>\n}); }

my @input = split /\n/, <<'__EOI__';
root
^^aa
^^^^bb
^^cc
^^dd
__EOI__

binmode(STDOUT, ':encoding(UTF-8)');
print(qq{<?xml version="1.0"?>\n});
于 2012-06-29T18:30:24.093 回答