Automation

last person joined: 4 days ago 

Ask questions and share experiences about Apstra, Paragon, and all things network automation.
  • 1.  perl: parsing get_configuration output with XML::LibXML

     
    Posted 05-17-2011 09:13

    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

       


  • 2.  RE: perl: parsing get_configuration output with XML::LibXML
    Best Answer

    Posted 05-17-2011 11:48

    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.



  • 3.  RE: perl: parsing get_configuration output with XML::LibXML

     
    Posted 05-18-2011 09:54

    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



  • 4.  RE: perl: parsing get_configuration output with XML::LibXML

     
    Posted 05-19-2011 01:39

    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;
    }