Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Missing values in XML::Twig Output

by TJRandall (Sexton)
on May 03, 2011 at 14:27 UTC ( [id://902726]=perlquestion: print w/replies, xml ) Need Help??

TJRandall has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to replace the first tag element of a XML file, using XML::Twig. I am trying to replace the first instance of <display-name> (in sample: 'wtw_reports-CIMS_MMA_20110429_DEV') with a custom tag from the build engine. When I print the XML file, I am missing the tags/data for all <display-name> that I wanted to replace. Any/all advice would be greatly appreciated! Thank you!
#!/usr/bin/perl use strict; use warnings; use XML::Twig; my $out_file = 'C:\web_bu.xml'; my $t = XML::Twig->new( twig_roots => {'display-name' => \&convert}, twig_print_outside_roots => 1, pretty_print => 'nice' ); # including data for ease of post #$t->parsefile( $file); $t->parse(*DATA); # export the XML open (my $fh_out, '>', $out_file) or die "unable to open '$out_file' f +or writing: $!"; $t->print($fh_out); # this prints to the filehandle #$t->print(); sub convert { my ($t, $elt) = @_; my $txt = $elt->text(); if ($txt =~ /wtw_reports/i) { $elt->set_text('SOMEGUY'); } else { $elt->set_text($txt); } } __DATA__ <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/n +s/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch +emaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ +ns/j2ee/web-app_2_4.xsd"> <display-name>wtw_reports-CIMS_MMA_20110429_DEV</display-name> <servlet> <display-name> Apache-Axis Servlet</display-name> <servlet-name>AxisServlet</servlet-name> <servlet-class> org.apache.axis.transport.http.AxisServlet</servlet-class> </servlet> <servlet> <display-name> Axis Admin Servlet</display-name> <servlet-name>AdminServlet</servlet-name> <servlet-class> org.apache.axis.transport.http.AdminServlet</servlet-class> <load-on-startup>100</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/servlet/AxisServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>*.jws</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AdminServlet</servlet-name> <url-pattern>/servlet/AdminServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>

Replies are listed 'Best First'.
Re: Missing values in XML::Twig Output
by mirod (Canon) on May 03, 2011 at 16:00 UTC

    When you use the twig_print_outside_roots option, the XML outside of the roots is output as soon as it is parsed. So you need to output the changed tags as soon as they are parsed too, ie in the handler, not after the end of the parse.

    So you code should look like this:

    open (my $fh_out, '>', $out_file) or die "unable to open '$out_file' f +or writing: $!"; my $t = XML::Twig->new( twig_roots => {'display-name' => sub { convert( @_, +$fh_out) } }, twig_print_outside_roots => $fh_out, # as mentioned in a previous +response pretty_print => 'nice' ); # including data for ease of post $t->parsefile( $file); sub convert { my ($t, $elt, $fh) = @_; ... # do what you have to do to $elt $elt->print( $fh); # this is where you have to print it }
Re: Missing values in XML::Twig Output
by toolic (Bishop) on May 03, 2011 at 14:37 UTC
    When I run your code, it seems to create an output file which matches your requirements (web_bu.xml). The 1st display-name text has been replaced, and the other 2 remain the same:
    <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/n +s/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch +emaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ +ns/j2ee/web-app_2_4.xsd"> <display-name>SOMEGUY</display-name> <display-name> Apache-Axis Servlet</display-name> <display-name> Axis Admin Servlet</display-name> </web-app>

    How do you want the output file to look?

      Ugh - I forgot to say that - I want the output to be the first display-name to have changed to 'SOMEGUY', with the others still intact:
      <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/n +s/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch +emaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ +ns/j2ee/web-app_2_4.xsd"> <display-name>SOMEGUY</display-name> <servlet> <display-name> Apache-Axis Servlet</display-name> <servlet-name>AxisServlet</servlet-name> <servlet-class> org.apache.axis.transport.http.AxisServlet</servlet-class> </servlet> <servlet> <display-name> Axis Admin Servlet</display-name> <servlet-name>AdminServlet</servlet-name> <servlet-class> org.apache.axis.transport.http.AdminServlet</servlet-class> <load-on-startup>100</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/servlet/AxisServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>*.jws</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AdminServlet</servlet-name> <url-pattern>/servlet/AdminServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
        When I run your code, it generates two outputs:
        • some to STDOUT
        • other to file web_bu.xml
        My guess is that you want all output to go to the file and none to STDOUT. Is that correct? So, what you just posted should be the contents of the output file?
        use strict; use warnings; use XML::Twig; my $out_file = 'C:\web_bu.xml'; my $t = XML::Twig->new( twig_handlers => {'display-name' => \&convert}, pretty_print => 'indented' ); $t->parse(*DATA); open (my $fh_out, '>', $out_file) or die "unable to open '$out_file' f +or writing: $!"; $t->print($fh_out); # this prints to the filehandle sub convert { my ($t, $elt) = @_; my $txt = $elt->text(); if ($txt =~ /wtw_reports/i) { $elt->set_text('SOMEGUY'); } }
Re: Missing values in XML::Twig Output
by eff_i_g (Curate) on May 03, 2011 at 15:15 UTC
    This is going to STDOUT:
    twig_print_outside_roots => 1,
    And this to the file:
    $t->print($fh_out);
    Try opening your file first and:
    twig_print_outside_roots => $fh_out,
      hmm - I think I made the changes correctly - I changed my code to:
      #!/usr/bin/perl use strict; use warnings; use XML::Twig; my $out_file = 'C:\web_bu.xml'; # export the XML open (my $fh_out, '>', $out_file) or die "unable to open '$out_file' f +or writing: $!"; my $t = XML::Twig->new( twig_roots => {'display-name' => \&convert}, twig_print_outside_roots => $fh_out, pretty_print => 'nice' ); # including data for ease of post #$t->parsefile( $file); $t->parse(*DATA); sub convert { my ($t, $elt) = @_; my $txt = $elt->text(); if ($txt =~ /wtw_reports/i) { $elt->set_text('SOMEGUY'); } else { $elt->set_text($txt); } } __DATA__ <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/n +s/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch +emaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ +ns/j2ee/web-app_2_4.xsd"> <display-name>wtw_reports-CIMS_MMA_20110429_DEV</display-name> <servlet> <display-name> Apache-Axis Servlet</display-name> <servlet-name>AxisServlet</servlet-name> <servlet-class> org.apache.axis.transport.http.AxisServlet</servlet-class> </servlet> <servlet> <display-name> Axis Admin Servlet</display-name> <servlet-name>AdminServlet</servlet-name> <servlet-class> org.apache.axis.transport.http.AdminServlet</servlet-class> <load-on-startup>100</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/servlet/AxisServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>*.jws</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AdminServlet</servlet-name> <url-pattern>/servlet/AdminServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
      But still get file with the missing <display-name> output:
      <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/n +s/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch +emaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ +ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>AxisServlet</servlet-name> <servlet-class> org.apache.axis.transport.http.AxisServlet</servlet-class> </servlet> <servlet> <servlet-name>AdminServlet</servlet-name> <servlet-class> org.apache.axis.transport.http.AdminServlet</servlet-class> <load-on-startup>100</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/servlet/AxisServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>*.jws</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AdminServlet</servlet-name> <url-pattern>/servlet/AdminServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
Re: Missing values in XML::Twig Output
by choroba (Cardinal) on May 03, 2011 at 21:21 UTC
    Using XML::XSH2:
    open 902726.xml ; register-namespace j http://java.sun.com/xml/ns/j2ee ; insert text 'SOMEGUY' replace //j:display-name[xsh:matches(.,'wtw_repo +rts')]/text() ; save :b ;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://902726]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (2)
As of 2024-04-20 05:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found