Во-первых, большое спасибо всем ответчикам!Теперь я чувствую, что должен предоставить реальные детали реальной задачи.
Я анализирую XML-файл, содержащий набор элементов, каждый из которых выглядит следующим образом:
<element>
<attr_1>value_1</attr_1>
<attr_2>value_2</attr_2>
<attr_3></attr_3>
</element>
MyЦель состоит в том, чтобы создать Perl-хеш для элемента, который содержит следующие ключи и значения:
('attr_1' => 'value_1',
'attr_2' => 'value_2',
'attr_3' => undef)
Давайте подробнее рассмотрим элемент <attr_1>
.Модуль XML::DOM::Parser
CPAN
, который я использую для разбора, создает для них объект класса XML::DOM::Element
, давайте дадим ему имя $attr
для справки.Имя элемента легко получить с помощью $attr->getNodeName
, но для доступа к тексту, заключенному в теги <attr_1>
, нужно сначала получить все дочерние элементы <attr_1>
:
my @child_ref = $attr->getChildNodes;
For <attr_1>
и <attr_2>
elements ->getChildNodes
возвращает список, содержащий ровно одну ссылку (на объект класса XML::DOM::Text
), в то время как для <attr_3>
он возвращает пустой список.Для <attr_1>
и <attr_2>
я должен получить значение на $child_ref[0]->getNodeValue
, а для <attr_3>
я должен поместить undef
в результирующий хеш, поскольку там нет текстовых элементов.
Итак, вы видите, что f
Реализация функции (метод ->getChildNodes
в реальной жизни) не может контролироваться :-) Полученный код, который я написал (подпрограмма снабжена списком XML::DOM::Element
ссылок для элементов <attr_1>
, <attr_2>
,и <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;
}