1

I have a settings.xml file as

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">

  <pluginGroups>
    <pluginGroup>org.mortbay.jetty</pluginGroup>
  </pluginGroups>
  <servers>
    <server>
      <id>server001</id>
      <username>my_login</username>
      <password>my_password</password>
      <privateKey>${user.home}/.ssh/id_dsa</privateKey>
      <passphrase>some_passphrase</passphrase>
      <filePermissions>664</filePermissions>
      <directoryPermissions>775</directoryPermissions>
      <configuration></configuration>
    </server>
  </servers>
</settings>

As seen, there is no proxy data. I would like to add data using Perl:Twig. I cannot use other CPAN modules, as the perl distribution is not maintained by me.

I have read the perl doc on twig, but I am confused on the insert process. I have also read this perl link, this SO link where comparison/copy of XML is used (not relevant here because I am not not comparing). Also I read SO twig child adding, but I think I want to create a tag. ThisSo link explains how to use XML::DOM, but I am limited to Perl:Twig, and lastly this SO on XML:Simple, but again I am limited to Perl:Twig, plus perldoc states do not use XML:Simple.

My current code looks similar to

my $t = XML::Twig->new(
    twig_roots   => { proxy => 1 },
    pretty_print => 'indented',
)->parsefile( $maven_Dir . "/" . $settings_File );

if ( !$t->root->children('proxy') ) {
    print(
        "In your settings.xml located in your .m2 folder, 
         there appears to be no proxy settings \n"
    );
    print("Adding Jlab proxy settings \n");
    my $cp = $t->root->children('settings');
    $cp->insert("proxies");

#       $cp->first_child('proxy');
#       $cp->paste( 'last_child', $t->root );

}
else {

    foreach my $proxy ( $t->root->children('proxy') ) {
        my $port     = $proxy->first_child_text('port');
        my $host     = $proxy->first_child_text('host');
        my $protocol = $proxy->first_child_text('protocol');
        my $active   = $proxy->first_child_text('active');

        if (   $port == 1492
            && $host eq "jpoop"
            && $protocol eq "http"
            && $active eq "true" )
        {
            print("Correct proxy settings are set properly for Jlab \n");
            print( "$port \n", "$host \n", "$protocol \n",
                "$active'\n \n" );

        }

    }
}

Would someone point me in the direction of adding data similar to

<proxies>
    <proxy>
        <active>true</active>
        <protocol>http</protocol>
        <host>jpoop</host>
        <port>1492</port>
    </proxy>
</proxies>

into an XML file using Perl:Twig?

Maerlyn
  • 33,687
  • 18
  • 94
  • 85
mkunkel
  • 243
  • 3
  • 16

1 Answers1

2

XML::Twig isn't the best to edit XML, but it can be done:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

use XML::Twig;

my ($PORT, $HOST, $PROTOCOL, $ACTIVE) = (1492, 'jpoop', 'http', 'true');

my $twig = 'XML::Twig'->new(
    pretty_print => 'indented',
)->parsefile(shift);

my $root = $twig->root;
my ($proxies) = $root->children('proxies');

if (! $proxies) {
    print STDERR
        "In your settings.xml located in your .m2 folder,
         there appears to be no proxy settings.
         Adding Jlab proxy settings \n";

    my $proxies = $root->insert_new_elt('proxies');
    $proxies->set_inner_xml(
        "<proxy><active>$ACTIVE</active><protocol>$PROTOCOL</protocol>"
        . "<host>$HOST</host><port>$PORT</port></proxy>");
    $root->print;

} else {
    my $found;
    for my $proxy ( $proxies->children('proxy') ) {
        my $port     = $proxy->first_child_text('port');
        my $host     = $proxy->first_child_text('host');
        my $protocol = $proxy->first_child_text('protocol');
        my $active   = $proxy->first_child_text('active');

        $found = 1 if $port == $PORT
                   && $host eq $HOST
                   && $protocol eq $PROTOCOL
                   && $active eq $ACTIVE;
    }
    if ($found) {
        print STDERR "Correct proxy settings are set properly for Jlab \n";
    } else {
        print STDERR "Correct proxy settings missing:\n",
            "port $PORT\nhost $HOST\nprotocol $PROTOCOL\nactive $ACTIVE\n";

    }
}
choroba
  • 231,213
  • 25
  • 204
  • 289
  • Wonderful, thanks for the clearly written example. May I suggest to add my $outDir = $maven_Dir . "/" . $settings_File; open (my $fh_out, '>', $outDir) or die "unable to open '$outDir' for writing: $!"; print{$fh_out} $twig->sprint(); In case people wish to know how to write the new file? Thanks again. – mkunkel May 29 '18 at 18:43
  • I would probably use `insert_new_elt` rather than `set_inner_xml` here I think. – Sobrique May 30 '18 at 09:59
  • @Sobrique: Sure, I'm not so familiar with all the Twig's methods. I'm more an XML::LibXML guy. Is there a compact way how to set the inner structure? – choroba May 30 '18 at 10:08