At first, much thanks for all repliers! Now I'm feeling that I should provide the actual details of the real task.
I'm parsing a XML file containing the set of element each looks like that:
<element>
<attr_1>value_1</attr_1>
<attr_2>value_2</attr_2>
<attr_3></attr_3>
</element>
My goal is to create Perl hash for element that contains the following keys and values:
('attr_1' => 'value_1',
'attr_2' => 'value_2',
'attr_3' => undef)
Let's have a closer look to <attr_1>
element. XML::DOM::Parser
CPAN
module that I use for parsing creates for them an object of class XML::DOM::Element
, let's give the name $attr
for their reference. The name of element is got easy by $attr->getNodeName
, but for accessing the text enclosed in <attr_1>
tags one has to receive all the <attr_1>
's child elements at first:
my @child_ref = $attr->getChildNodes;
For <attr_1>
and <attr_2>
elements ->getChildNodes
returns a list containing exactly one reference (to object of XML::DOM::Text
class), while for <attr_3>
it returns an empty list. For the <attr_1>
and <attr_2>
I should get value by $child_ref[0]->getNodeValue
, while for <attr_3>
I should place undef
into the resulting hash since no text elements there.
So you see that f
function's (method ->getChildNodes
in real life) implementation could not be controlled :-) The resulting code that I have wrote is (the subroutine is provided with list of XML::DOM::Element
references for elements <attr_1>
, <attr_2>
, and <attr_3>
):
sub attrs_hash(@)
{
my @keys = map {$_->getNodeName} @_; # got ('attr_1', 'attr_2', 'attr_3')
my @child_refs = map {[$_->getChildNodes]} @_; # got 3 refs to list of XML::DOM::Text objects
my @values = map {@$_ ? $_->[0]->getNodeValue : undef} @child_refs; # got ('value_1', 'value_2', undef)
my %hash;
@hash{@keys} = @values;
%hash;
}
f
so that when it returns an empty list, you supplyundef
or otherwise the first element of the list it returned. – Sheepish