in reply to XML replacenode

The code as posted doesn't work. Where does $node_c come from?

If you want to fill a node regardless of whether it contains any text, don't use its text contents - as there can be none. Clean the node instead and add the new text:

#! /usr/bin/perl use strict; use feature qw{ say }; use warnings; use XML::LibXML; my $xml = '<header> <id x_id="1"> <a></a> <b></b> <c>NA</c> </id> </header>'; print "Please specify node c content: "; chomp( my $new_text = <STDIN> ); my $dom = 'XML::LibXML'->load_xml(string => $xml); for my $node($dom->findnodes('(/header/id/b | /header/id/c)')) { $node->removeChildNodes; $node->appendText($new_text); } print $dom;

Or, try XML::XSH2:

open file.xml ; for (/header/id/b|/header/id/c) set text() "YOUR TEXT HERE" ; save :b ;

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^2: XML replacenode
by michael99 (Acolyte) on Apr 16, 2020 at 01:02 UTC

    Hi, it was a typo in my original post. I tried your code and it shows XML::LibXML::Document=SCALAR(0x6e7fd0)

      I edited it to load file from my cwd. It seems still interrupting empty node: Code:
      #! /usr/bin/perl use strict; use feature qw{ say }; use warnings; use XML::LibXML; print "Please specify node c content: "; chomp( my $new_text = <STDIN> ); my $file = 'xx.xml'; my $dom = 'XML::LibXML'->load_xml(location => $file); for my $node($dom->findnodes('(/header/id/c)')) { $node->removeChildNodes; $node->appendText($new_text); } #print $dom; open (my $Output, "> $file") or die "Could not write $file"; print $Output $dom->toString(); close ($Output) or die "Could not close generated $file ";
      Output:
      <?xml version="1.0"?> <header> <id x_id="1"> <a/> <b/> <c>as</c> </id> </header>
      Expecting output:
      <?xml version="1.0"?> <header> <id x_id="1"> <a></a> <b></c> <c>something</c> </id> </header>

        The difference between your observed and expected output appears to be down to canonicalisation. See eg:

        #!/usr/bin/env perl use strict; use warnings; use XML::LibXML; my $dom = XML::LibXML->load_xml (string => <<'EOT'); <?xml version="1.0"?> <header> <id x_id="1"> <a/> <b/> <c>as</c> </id> </header> EOT print "\nNot canonical:\n\n" . $dom->toString; print "\nWith canonical:\n\n" . $dom->toStringC14N;