Search code examples
xmlperlxml-simplexml-twig

Change an XML file content via Perl script


This thread is in continuation of Perl script to populate an XML file.

The file I want to change is:

<?xml version="1.0" encoding="UTF-8"?>
  <configuration start="earth">
    <country-list>
      <country name="japan">
        <description></description>
        <start>1900</start>
        <end/>
      </country>
      <country name="italy">
        <description></description>
        <start>1950</start>
        <end/>
      </country>
      <country name="korea">
        <description></description>
        <start>1800</start>
        <end/>
      </country>
    </country-list>
  </configuration>

I want to add a new country here in this list.

In previous question, Perl script to populate an XML file.

#Get the list of cities as a list, then push "Tokyo" to it.
push @{$doc->{countries}->{country}->{'japan-'}->{city}}, 'Tokyo';

This was suggested to add a new tag, but in my case not sure how exactly can I use "push". I am not able to map to the correct tag.


Solution

  • I find XML::DOM a lot simpler to use. It may be a bit verbose, but you can easily understand what it is doing.

    use XML::DOM;
    
    #parse the file
    my $parser = new XML::DOM::Parser;
    my $doc = $parser->parsefile ("test.xml");
    my $root = $doc->getDocumentElement();
    
    #get the country-list element
    my $countryListElement = pop(@{$root->getElementsByTagName('country-list')}); 
    
    #create a new country element
    my $newCountryElement= $doc->createElement('country');
    $newCountryElement->setAttribute("name","England");
    
    my $descElement= $doc->createElement('description');
    $newCountryElement->appendChild($descElement);
    
    my $startElement= $doc->createElement('start');
    my $startTextNode= $doc->createTextNode('1900');
    $startElement->appendChild($startTextNode);
    $newCountryElement->appendChild($startElement);
    
    my $endElement= $doc->createElement('end');
    $newCountryElement->appendChild($endElement);
    
    #add the country to the country-list
    $countryListElement->appendChild($newCountryElement);
    
    #print it out
    print $doc->toString;
    
    #print to file
    $doc->printToFile("out.xml");