Junos Automation (Scripting)
Reply
Recognized Expert
Mattia
Posts: 198
Registered: ‎03-17-2010
0
Accepted Solution

perl: parsing get_configuration output with XML::LibXML

[ Edited ]

Hi, I am experiencing a weird behaviour of the method load_xml of the module XML::LibXML.

I can parse without problems the output of "operational" commands (e.g. "get _interface_information"), but I can't parse the output of the method get_configuration!

 

This is the code I am using:

 

my $jnx = new JUNOS::Device(%deviceinfo);
unless ( ref $jnx ) { print "ERROR: : failed to connect to $deviceinfo{hostname}.\n"; exit}
	
my $res; # command XML output
	
if (%queryargs){ $res = $jnx->$query( %queryargs ); } else { $res = $jnx->$query; }
unless ( ref $res ) 
{ print "ERROR: $deviceinfo{hostname}: failed to execute command $query.\n"; $jnx->request_end_session(); $jnx->disconnect(); exit; } my $err = $res->getFirstError();
if ($err) { print STDERR "ERROR: - ", $err->{message}, "\n"; $jnx->request_end_session(); $jnx->disconnect(); exit; }
else { my $xmlfile = "$deviceinfo{hostname}.xml"; $res->printToFile($xmlfile); $xml_string = xml_loadfile( $xmlfile ); print STDERR "Creating DOM element\n";
my $dom = XML::LibXML->load_xml( string => $xml_string );
print STDERR "\n DOM element created.\n";

 $command_output = $dom->documentElement; # unlink $xmlfile; }
$jnx->request_end_session();
$jnx->disconnect();

# print "Connection closed.\n";

return $command_output;

The execution of the line my $dom = XML::LibXML->load_xml( string => $xml_string ) is somehow failing, and aborting execution,  when xml_string is the output of get_configuration. Otherwise, it works fine...

 

Note that the xmlfile is created correctly! The only difference between the file created from "get_interface_description" and "get_configuration" is in the indentation of text:

 

[extract of get_interface_information xml file]

 

<interface-information xmlns="http://xml.juniper.net/junos/10.4R4/junos-interface" junos:style="normal">

<physical-interface>

<name>ge-1/0/0</name>

<admin-status junos:format="Enabled">up</admin-status>

<oper-status>up</oper-status>

<local-index>179</local-index>

<snmp-index>572</snmp-index>

 [extract of get_configuration xml file]

 

 

<configuration junos:changed-localtime="2011-05-17 13:26:03 CEST" junos:changed-seconds="1305631563">

    <version>10.4R4.5</version>

    <groups>

        <name>re0</name>

        <system>

            <host-name>JUNOS-1_re0</host-name>

        </system>

        <interfaces>

            <interface>

                <name>fxp0</name>

 

 

I also noticed that during the execution of the script that is giving the error, I have the following output on the target router:

"May 17 18:05:35  JUNOS-1_re0 file[60970]: LIBJNX_EXEC_SELECT: Unable to select input stream for command 'fbuf pipe': Bad file descriptor"

 

 

Does anybody know what may be causing this issue?

 

Thanks in advance for your help,

Mattia

   
.................................................................................
JNCIP-ENT, JNCIP-SEC, JNCIS-SP
(If this post helped you, please mark it as an "Accepted Solution"; kudos are also appreciated!)


Super Contributor
jschulman
Posts: 145
Registered: ‎11-03-2009
0

Re: perl: parsing get_configuration output with XML::LibXML

I ran into some issues having to do with namespaces not being defined, but that may not be the issue you are having.  I'd suggest try stripping the namespace references out of the XML.

Cheers,
-- Jeremy

@nwkautomaniac
Recognized Expert
Mattia
Posts: 198
Registered: ‎03-17-2010
0

Re: perl: parsing get_configuration output with XML::LibXML

Hello Jeremy, thanks for your reply! You hit the point, the problem was indeed related to not declared namespace; I am still a bit confuse though, cause I was already using the xml_loadfile subroutine that you provided (here) to strip attributes off, but still the load_xml method was failing.

 

So I had to change the logic of my script, using the parsefile method instead of load_xml... I'm not sure about what happened, anyway now the script is working fine, so I'm satisfied :-)

 

Thanks again for your help,

 

Best Regards

Mattia

.................................................................................
JNCIP-ENT, JNCIP-SEC, JNCIS-SP
(If this post helped you, please mark it as an "Accepted Solution"; kudos are also appreciated!)


Recognized Expert
Mattia
Posts: 198
Registered: ‎03-17-2010
0

Re: perl: parsing get_configuration output with XML::LibXML

[ Edited ]

I ran again into the same problem, and I made some deeper analysis...I would like to share the results with the forum users.

It turned out that the sub xml_loadfile was matching, beyond the attributes, also part of the <ieee-802.3ad> opening tag, which after the processing was becoming just <ieee-802>.

 

This caused the xml parser to file, cause the closing tag remained <802.3.ad>.

 

As an example:

original xml:

                <ieee-802.3ad>

                    <bundle>ae3</bundle>

                </ieee-802.3ad>

xml after the attribute stripping:

                <ieee-802>

                    <bundle>ae3</bundle>

                </ieee-802.3ad>

 

So I edited the  subroutine provided by Schulman, in order to have the .ad to be matched, this way (the bold part is what I added):

sub xml_loadfile
{
    my ($xml_filename) = @_;
    my $xml_string = '';
    open (XML, $xml_filename);
    while(<XML>)
    {
         s/(<[\w-\.]+)(.*?)(\/?>)/\1\3/m;    # remove attributes
        $xml_string .= $_;
    }

    close (XML);
    return $xml_string;
}

 

 

.................................................................................
JNCIP-ENT, JNCIP-SEC, JNCIS-SP
(If this post helped you, please mark it as an "Accepted Solution"; kudos are also appreciated!)


Copyright© 1999-2013 Juniper Networks, Inc. All rights reserved.