To close out this discussion, here's an example implementation using XML::LibXML of taking the example data, finding a specific node, editing that node, and adding a new node after it, and outputting the final XML to complete the round trip.
#!perl -l
use 5.012; # strict, //
use warnings;
use Data::Dump;
use XML::LibXML;
my $xml_doc = <<EOXML;
<?xml version="1.0" encoding="UTF-8" ?>
<!-- important instructions to manual editors -->
<root>
<group name="somethingElse">
<Item MenuEntryName="Edit" MenuItemName="Copy"/>
</group>
<group name="contextMenu">
<!-- still commented -->
<Item MenuEntryName="Edit" MenuItemName="Cut"/>
<Item MenuEntryName="Edit" MenuItemName="Copy"/>
<Item MenuEntryName="Edit" MenuItemName="Paste"/>
</group>
</root>
EOXML
# process XML
my $dom = XML::LibXML->load_xml(string => $xml_doc, no_blanks => 1);
# find specific item and its parent
my ($desiredItem) = $dom->findnodes('//group[@name="contextMenu"]/Item
+[@MenuItemName="Copy"]');
printf "%-23s %s\n", "Found:", $desiredItem->toString();
my $itemParent = $desiredItem->parentNode;
printf "%-23s %s\n", "Parent:", $itemParent->toString(1);
# prove that I can edit the item
$desiredItem->setAttribute( comment => 'edited' );
printf "%-23s %s\n", "Edited:", $desiredItem->toString();
printf "%-23s %s\n", "Parent:", $itemParent->toString(1);
# create item and show it's not added to parent yet
my $newItem = XML::LibXML::Element->new('Item');
$newItem->setAttribute( MenuEntryName => "Edit");
$newItem->setAttribute( MenuItemName => "Delete");
$newItem->setAttribute( comment => "created");
printf "%-23s %s\n", "Created:", $newItem->toString();
printf "%-23s %s\n", "Parent:", $itemParent->toString(1);
# add item
$itemParent->insertAfter($newItem, $desiredItem);
printf "%-23s %s\n", "Added to Parent:", $itemParent->toString(1);
# verify it's there and edit it
my ($foundNew) = $dom->findnodes('//group[@name="contextMenu"]/Item[@c
+omment="created"]');
printf "%-23s %s\n", "Found:", $foundNew->toString();
$foundNew->setAttribute( comment => 'inserted' );
printf "%-23s %s\n", "Edited:", $foundNew->toString();
printf "%-23s %s\n", "Parent:", $itemParent->toString(1);
# finish with the Round Trip output
my $str = $dom->toString(1);
$str =~ s/(^|\G)( |\t)/ /gm;
print "\n\nRound Trip output:\n-----\n$str\n=====\n\n";
__END__
... snipped intermediate output ...
Round Trip output:
-----
<?xml version="1.0" encoding="UTF-8"?>
<!-- important instructions to manual editors -->
<root>
<group name="somethingElse">
<Item MenuEntryName="Edit" MenuItemName="Copy"/>
</group>
<group name="contextMenu">
<!-- still commented -->
<Item MenuEntryName="Edit" MenuItemName="Cut"/>
<Item MenuEntryName="Edit" MenuItemName="Copy" comment="edited
+"/>
<Item MenuEntryName="Edit" MenuItemName="Delete" comment="inse
+rted"/>
<Item MenuEntryName="Edit" MenuItemName="Paste"/>
</group>
</root>
=====
So thanks all for the helpful suggestions.