<?xml version="1.0" encoding="windows-1252"?>
<node id="1019196" title="How to remove empty XML elements using XML::LibXML" created="2013-02-17 14:22:54" updated="2013-02-17 14:22:54">
<type id="115">
perlquestion</type>
<author id="690111">
FreakyGreenLeaky</author>
<data>
<field name="doctext">
&lt;p&gt;
Evening robe-rufflers... I have next to zero experience with XML and XML::LibXML and I hope someone can shed some light on the following.&lt;/p&gt;

&lt;p&gt;Basically, I want to remove some empty elements in XML.&lt;/p&gt;

&lt;code&gt;
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"&gt;
  &lt;command&gt;
    &lt;update&gt;
      &lt;contact:update xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:contact-1.0 contact-1.0.xsd"&gt;
        &lt;contact:id&gt;testaccount3&lt;/contact:id&gt;
        &lt;contact:add/&gt;
        &lt;contact:rem/&gt;
&lt;/code&gt;

&lt;p&gt;I need to remove those last two empty elements, but I'm guessing the namespace stuff (or something) is a factor.&lt;/p&gt;

&lt;p&gt;I've naively tried the following:&lt;/p&gt;
&lt;code&gt;
for my $remove ($frame-&gt;findnodes(q{/command/update/contact:update/contact:add})) {
    $remove-&gt;unbindNode;
}
&lt;/code&gt;
&lt;p&gt;
&lt;b&gt;Edit:&lt;/b&gt; using the above findnodes() results in the error:&lt;/p&gt;
&lt;code&gt;XPath error : Undefined namespace prefix
 error : xmlXPathCompiledEval: evaluation failed
&lt;/code&gt;


But I must admit I'm clueless here and would appreciate some pointers.

&lt;p&gt;
&lt;b&gt;Update:&lt;/b&gt;&lt;br&gt;
I've been looking at the source which creates the XML:&lt;br&gt;
&lt;code&gt;/usr/lib/perl5/site_perl/5.8.8/Net/EPP/Frame/Command/Update/Contact.pm&lt;/code&gt;&lt;br&gt;&lt;br&gt;

&lt;code&gt;
sub new {
    my $package = shift;
    my $self = bless($package-&gt;SUPER::new('update'), $package);

    my $contact = $self-&gt;addObject(Net::EPP::Frame::ObjectSpec-&gt;spec('contact'));

    foreach my $grp (qw(add rem chg)) {
        my $el = $self-&gt;createElement(sprintf('contact:%s', $grp));
        $self-&gt;getNode('update')-&gt;getChildNodes-&gt;shift-&gt;appendChild($el);
    }

    return $self;
}
&lt;/code&gt;

And I must confess to being mightily tempted to just remove &lt;code&gt;add rem&lt;/code&gt; from the &lt;code&gt;foreach&lt;/code&gt;.  This works, but it makes me feel decidedly dirty - and I might need those elements in the future.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Solution:&lt;/b&gt;&lt;br&gt;

&lt;code&gt;
my $p = $frame-&gt;getElementsByTagName('contact:update');
    foreach my $n ($p-&gt;[0]-&gt;childNodes()) {
        $p-&gt;[0]-&gt;removeChild($n) if $n-&gt;toString(1) eq "&lt;contact:add/&gt;";
    }
&lt;/code&gt;

Not very elegant, but it works.  If someone knows of a better way, I'd love to hear it.
&lt;/p&gt;</field>
</data>
</node>
