jdbaldwin23 has asked for the wisdom of the Perl Monks concerning the following question:
I am trying to use XML::Twig to convert a policy (call it a firewall policy, but that's not strictly true) from one format to another. Call the existing file format "OLDFW" and the new format "NEWFW." I have boiled the problem down to bare-essentials XML below.
OLDFW has a root called "policy" which contains one element and one only: "policyrules". That element contains many "Rule" elements which in turn have sub-elements, etc.
NEWFW should be the same (actually there are changes, but I don't need help with that), except the <policyrules> element is eliminated -- that is, all the "Rule" elements are directly underneath "<policy>".
I know that if I simply ignore or delete <policyrules>, I lose all the children. I want to build a handler to skip over it, but that's the problem.
I have kludged around the problem by filtering out <policyrules> before XML-parsing the file, but I am now wondering whether there is a more elegant solution where I can simply tell XML::Twig (or whatever) to "promote" all the "Rule" elements to the same level as "policyrules" and then delete the latter.
Here's a sample OLDFW:
<?xml version="1.0" encoding="UTF-8"?> <policy name="Cur_policy" version="3.2.1"> <policyrules> <Rule Action="allow" Enabled="true" RuleID="F68E32"> <source addr="10.4.5.3" srcport="any"/> <dest addr="199.5.4.3" destport="80"/> </Rule> <Rule Action="allow" Enabled="true" RuleID="78E21D"> <source addr="10.4.0.0-10.4.255.255" srcport="any"/> <dest addr="any" destport="80"/> </Rule> </policyrules> </policy>
The NEWFW I'd like to get:
<?xml version="1.0" encoding="UTF-8"?> <policy name="Cur_policy" version="3.2.1"> <Rule Action="allow" Enabled="true" RuleID="F68E32"> <source addr="10.4.5.3" srcport="any"/> <dest addr="199.5.4.3" destport="80"/> </Rule> <Rule Action="allow" Enabled="true" RuleID="78E21D"> <source addr="10.4.0.0-10.4.255.255" srcport="any"/> <dest addr="any" destport="80"/> </Rule> </policy>
The code I'm playing with -- what I need is "what goes into policyrules_handler?"
#!/usr/bin/perl use warnings; use strict; use XML::Twig; my ( $in_XML_file, $out_XML_file ) = @ARGV; # create objects my $ref_reader = XML::Twig->new( twig_handlers => { 'policyrules' => \&policyrules_ +handler, 'Rule' => \&rule_handler } ); $ref_reader->parsefile( $in_XML_file ) or die " $in_XML_file is not parsable\n"; open my $out_fh, '>', $out_XML_file or die " $out_XML_file cannot be written: $!"; $ref_reader->print( $out_fh ); close $out_fh; sub policyrules_handler { my( $t, $elt)= @_; # arguments for all twig_handlers # $elt->delete; } sub rule_handler { my( $t, $elt)= @_; # arguments for all twig_handlers $elt->set_att( 'new_attr' => 'dummyValue' ); }
Thank you for any assistance you can provide here.
jd
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Remove level of elements (preserving their children) in XML::Twig?
by BrowserUk (Patriarch) on Mar 01, 2012 at 04:35 UTC | |
|
Re: Remove level of elements (preserving their children) in XML::Twig?
by derby (Abbot) on Feb 29, 2012 at 22:57 UTC | |
|
Re: Remove level of elements (preserving their children) in XML::Twig?
by mirod (Canon) on Mar 01, 2012 at 03:58 UTC | |
by jdbaldwin23 (Initiate) on Mar 01, 2012 at 19:06 UTC | |
|
Re: Remove level of elements (preserving their children) in XML::Twig?
by tobyink (Canon) on Feb 29, 2012 at 23:32 UTC | |
by tobyink (Canon) on Mar 01, 2012 at 03:05 UTC | |
|
Re: Remove level of elements (preserving their children) in XML::Twig?
by choroba (Cardinal) on Mar 01, 2012 at 11:22 UTC |