in reply to parse xml

As I can't test your code easilly I will venture 2 hypothesis: either you have a Perl problem, please use strict;, some of your variables are not declared, or you have a DOM-induced problem with \n and generally whitespaces creating text nodes when you are not expecting them, see my comment in the code.

The following works for me, I just took your code, extracted the relevant function and got it to work:

#!/bin/perl -w use strict; use XML::DOM; my $xml; $xml=change_dcr_attr (\*DATA, "change", "changed text", "string"); print $xml; sub change_dcr_attr { my ($dcr,$element_name,$element_value,$type) = @_; my $parser=new XML::DOM::Parser; my $dcr_doc; # COMMENT was not declared #parse the document print "type : $type \n"; # COMMENT you had $what here if ($type eq "file"){ $dcr_doc=$parser->parsefile($dcr) || die "unable to parse d +ocument: $!"; } else { $dcr_doc=$parser->parsestring($dcr) || die "unable to parse + document: $!" } #get all tags # COMMENT: unless you're into heavy B&D there is no need to write Ja +va # in Perl # my $dcr_items = $dcr_doc->getElementsByTagName('item'); # # iterate over all tags # # for my $i (0..$dcr_items->getLength-1) { # my $dcr_item=$dcr_items->item($i); # This is simpler foreach my $dcr_item ($dcr_doc->getElementsByTagName('item')) { # get the value of the name attrribute my $dcr_item_name = $dcr_item->getAttribute("name"); #process only required field #e.g.?Surname? next unless $dcr_item_name eq $element_name; # drill down to the tag my $dcr_item_child = $dcr_item->getFirstChild; # COMMENT: VERY + dangerous # if a \n or a +comment slips in # you should lo +op until you get # an element # COMMENT this saves you when you come across the last item below $dcr_item_child= $dcr_item_child->getNextSibling until( $dcr_item_child->getNodeType == ELEMENT_NODE); # get down to the text we want to change my $dcr_text_node = $dcr_item_child->getFirstChild if defined +$dcr_item_child; if (defined ($dcr_text_node)) { if (( $dcr_text_node->getNodeType == TEXT_NODE) ) { # finally change the value $dcr_text_node->setData($element_value); } } else { if ($type eq "string"){ print "Error\n"; return 0; } } } return $dcr_doc->toString; #return the whole DCR XML as a string } __DATA__ <doc> <item name="change"><sub>text to be changed</sub></item> <item name="change"><sub>text to be changed</sub></item> <item name="do not change"><sub>should remain unchanged</sub></item> <item name="change"> <sub>text to be changed</sub> </item> </doc>