Ошибка при использовании опции XML для Perl XML :: Tidy - PullRequest
0 голосов
/ 22 апреля 2011

Я хотел бы спросить вас, когда я хочу привести в порядок вложенный файл, используя:

my $tidy_doc = XML::Tidy->new("filename"=>"/Users/.../tidy.xml") ;
$tidy_doc->tidy() ;
$tidy_doc->write() ;

работает просто отлично, но когда я хочу привести в порядок, используя:

my $tidy_doc = XML::Tidy->new("xml"=>$doc) ;

Я получаю следующую ошибку:

bash-3.2# ./_demo.pl 
Use of uninitialized value $xmld in substitution (s///) at /Library/Perl/5.10.0/XML/Tidy.pm line 59.
Use of uninitialized value $xmld in pattern match (m//) at /Library/Perl/5.10.0/XML/Tidy.pm line 60.

not well-formed (invalid token) at line 1, column 21, byte 21:
XML::LibXML::Document=SCALAR(0x100805140)
====================^
 at /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level/XML/Parser.pm line 187

Буду признателен, если вы поможете мне в этом.

PS. XML-файл имеет следующий вид:

<?xml version="1.0" encoding="UTF-8"?>
<n_skalis>
    <perfdata collection="GigabitEthernet0/0">
        <info cmd="show interface" detail="GigabitEthernet0/0">


        <input_rate>-1</input_rate><output_rate>-1</output_rate></info>
        <info cmd="show interface" detail="GigabitEthernet0/0/1">

        <output_rate>-1</output_rate></info>
    </perfdata>
    <perfdata collection="GigabitEthernet1/1">
        <info cmd="show interface" detail="GigabitEthernet1/1">


        <input_rate>-1</input_rate><output_rate>-1</output_rate></info>
        <info cmd="show interface" detail="GigabitEthernet1/1/0">

        <output_rate>-1</output_rate></info>
    </perfdata>
    <perfdata collection="self">
        <info cmd="show buffers summary" detail="">


        <big_pool>-1</big_pool><small_pool>-1</small_pool></info>
    </perfdata>
</n_skalis>

спасибо

PS. $ doc определяется следующим образом:

my $doc = $parser->parse_file("$XMLDEV"."config/".$node_dns."/STATS.xml") ;
if( !$doc ) { warn "---> non well-formed XML file: $@" ; next ; }
my $root = $doc->getDocumentElement ;

Ответы [ 2 ]

1 голос
/ 22 апреля 2011

Предполагая, что используемая вами функция parse_file является частью модуля, такого как XML :: LibXML, проблема в том, что вы предоставляете XML :: Tidy структуру данных, сгенерированную модулем, который вы используете.XML :: Tidy ожидает простой текст XML-документа.

Вы должны сделать что-то вроде:

#!/usr/bin/perl
use strict;
use warnings;

my $doc;

# use an anonymous code block to limit the scope of the IRS unset
{
    # unset IRS (input record seperator) 
    # this allows us to read whole file at once
    local $/=undef;
    # open file
    open my $fh,"<","./test.xml"
        or die "Could not open file: $!";
    # read entire file into scalar variable
    $doc = <$fh>;
    # close file
    close $fh;
}

# process file content with XML::Tiday
my $tidy_doc = XML::Tiday->new(xml => $doc);
$tidy_doc->tidy();
$tidy_doc->write("output.xml");

Альтернатива, которая использует модуль LibXML:

# create XML::LibXML::Document object
my $doc = $parser->parse_file("./test.xml");

# use the the toString function to extract the XML content from the object
my $tidy_doc = XML::Tiday->new(xml => $doc->toString);
$tidy_doc->tidy();
$tidy_doc->write("output.xml");

Обратите внимание, что это должно быть сделано в качестве последнего шага обработки вашего XML, так как он экспортирует содержимое XML через сериализацию.Дальнейшие операции над объектом $doc не будут отражены в $tidy_doc.

В качестве отступления, пожалуйста, примите ответы, которые решают ваши вопросы, нажав на флажок рядом с ними.

https://stackoverflow.com/faq#howtoask

0 голосов
/ 22 апреля 2011

Я не получаю сообщение об ошибке с этим кодом:

use warnings;
use strict;
use XML::Tidy;

my $doc = <<EOF;
<?xml version="1.0" encoding="utf-8"?>
<inode>
<perfdata collection="GigabitEthernet0/0">
<info cmd="show interface" detail="GigabitEthernet0/0">
<input_rate>show_interface_input_rate.tcl</input_rate>
<output_rate>show_interface_output_rate.tcl</output_rate>
</info>
<info cmd="show interface" detail="GigabitEthernet0/0/1">
<output_rate>show_interface_output_rate.tcl</output_rate>
</info>
</perfdata>
<perfdata collection="GigabitEthernet1/1">
<info cmd="show interface" detail="GigabitEthernet1/1">
<input_rate>show_interface_input_rate.tcl</input_rate>
<output_rate>show_interface_output_rate.tcl</output_rate>
</info>
<info cmd="show interface" detail="GigabitEthernet1/1/0">
<output_rate>show_interface_output_rate.tcl</output_rate>
</info>
</perfdata>
<perfdata collection="self">
<info cmd="show buffers summary" detail="">
<big_pool>show_buffers_summary_big_pool.tcl</big_pool>
<small_pool>show_buffers_summary_small_pool.tcl</small_pool>
</info>
</perfdata>
</inode>
EOF

my $tidy_doc = XML::Tidy->new(xml => $doc);
$tidy_doc->tidy();
$tidy_doc->write('out.xml');

Я намеренно удалил все отступы. Файл out.xml, который я получаю, имеет правильный отступ.

...