Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

Navigation

Parsing and Formatting the Response from the NETCONF Server in NETCONF Perl Client Applications

In a NETCONF Perl Client application, as the last step in sending a request, the application verifies that there are no errors with the response from the NETCONF server. It can then write the response to a file, to the screen, or both. If the response is for an operational query, the application usually uses XSLT to transform the output into a more readable format, such as HTML or formatted ASCII. If the response consists of configuration data, the application can store it as XML (the Junos XML tag elements generated by default from the NETCONF server) or transform it into formatted ASCII text.

The following code sample from the diagnose_bgp.pl script included in the NETCONF Perl distribution uses XSLT to transform an operational response from the NETCONF server into a more readable format. A detailed discussion of the functional subsections follows the complete code sample.

# Get the output file
my $outputfile = $opt{'o'} || "";

# Get the xsl file
my $xslfile = $opt{'x'} || "xsl/bgp.xsl";

# Check for the existence of the given file
if (! -f $xslfile) {
    croak "XSL file $xslfile does not exist.";
}

# Get the xmlfile
my $xmlfile = $opt{'f'} || "xsl/bgp.xml";

# send the command and get the server response
my $res = $jnx->$query();

# print the server response into xmlfile
print_response($xmlfile, $jnx->{'server_response'});

# See if you got an error
if ($jnx->has_error) {
    croak "ERROR: in processing request \n $jnx->{'request'} \n";
} else {
    # Transform the server response using XSL file
    my $res = new Net::Netconf::Transform();
    print "Transforming ...\n";
    my $nm = $res->translateXSLtoRelease('xmlns:lc', $xslfile,
                                         "$xslfile.tmp",
                                         $xmlfile);
    if ($nm) {
        format_by_xslt($nm, $xmlfile, );
    } else {
        print STDERR "ERROR: Invalid XSL File $xslfile\n";
    }
}

The first line of the preceding code sample illustrates how the scripts read the -o option from the command line to obtain the name of the file into which to write the results of the XSLT transformation:

my $outputfile = $opt{'o'} || "";

From the -x command-line option, the scripts obtain the name of the XSLT file to use, setting a default value if the option is not provided. The scripts exit if the specified file does not exist. The following example is from the diagnose_bgp.pl script:

my $xslfile = $opt{'x'} || "xsl/bgp.xsl";
if (! -f $xslfile) {
    croak "XSL file $xslfile does not exist.";
}

For examples of XSLT files, see the following directories in the NETCONF Perl distribution:

  • The examples/diagnose_bpg/xsl directory contains an XSLT file for the diagnose_bpg.pl script.
  • The examples/get_chassis_inventory/xsl directory contains XSLT files for the get_chassis_inventory.pl script.

The actual parsing operation invokes the translateXSLtoRelease function (defined in the Net::Netconf::Transform module) to alter one of the namespace definitions in the XSLT file.

my $res = new Net::Netconf::Transform();
    print "Transforming ...\n";
    my $nm = $res->translateXSLtoRelease('xmlns:lc', $xslfile, 
                                         "$xslfile.tmp",
                                         $xmlfile);
    if ($nm) {
        format_by_xslt($nm, $xmlfile, );
    } else {
        print STDERR "ERROR: Invalid XSL File $xslfile\n";
    }

This is necessary because the XSLT 1.0 specification requires that every XSLT file define a specific value for each default namespace used in the data being transformed. The xmlns attribute in a NETCONF operational response tag element includes a code representing the Junos OS version, such as10.3R1 for the initial version of Junos OS Release 10.3. Because the same XSLT file can be applied to operational response tag elements from devices running different versions of the Junos OS, the XSLT file cannot predefine an xmlns namespace value that matches all versions. The translateXSLtoRelease function alters the namespace definition in the XSLT file identified by the $xslfile variable to match the value in the NETCONF server's response. It assigns the resulting XSLT file to the $nm variable.

After verifying that the translateXSLtoRelease function succeeded, the script invokes the format_by_xslt function, which builds a command string and assigns it to the $command variable. The first part of the command string invokes the xsltproc command and specifies the names of the XSLT and configuration data files ($xslfile and $xmlfile)::

sub format_by_xslt
{
    my ($xslfile, $xmlfile, $outfile)  = @_;

    print "Transforming $xmlfile with $xslfile...\n" if $outfile;
    my $command = "xsltproc $xslfile $xmlfile";
    $command .= "> $outfile" if $outfile;
    system($command);
    print "Done\n" if $outfile;
    print "See $outfile\n" if $outfile;
}

If the $outfile variable is defined (the file for storing the result of the XSLT transformation exists), the script appends a string to the $command variable to write the results of the xsltproc command to the file. (If the file does not exist, the script writes the results to standard out [stdout].) The script then invokes the system function to execute the command string and prints status messages to stdout.

If the translateXSLtoRelease function fails (the if ($nm) expression evaluates to “false”), the script prints an error:

if ($nm) {
     format_by_xslt($nm, $xmlfile, );
} else {
     print STDERR "ERROR: Invalid XSL File $xslfile\n";
}

Published: 2013-07-26