2015-01-12 1 views
0

У меня много многоузловых XML-файлов, которые я обрабатываю с помощью XML::Simple. Пока это отлично работает. Одна из первых вещей, которые я делаю, это получить длину XML файла (кол-узла) с помощью этого:Проблема с одноузловым XML-файлом в Perl

my $xmltemp = XML::Simple->new(
    SuppressEmpty => 1 
); 

my $product = $xmltemp->XMLin('xml/' . $basename . '.xml'); 

my $qfr = @{ $product->{$basename}}; 
print "$qfr = qfr\n"; 

Переменная $basename предоставляется обернув через массив имен файлов. Номенклатура и имя файла совпадают.

Это работает во всех файлах, кроме файлов, имеющих только один узел. Баки программы при попытке создать переменную $qfr.

Если я редактирую один из одноузловых XML-файлов и создаю другой узел (обманываем существующий) и повторно запускаем, это отлично работает.

Что не так, что XML-узел одного узла не отвечает на простое назначение скалярной переменной?

Линия print даже не выполняется.

ПРИМЕЧАНИЕ. Я разрезал и вставил важные биты кода из .pl и и .pm, чтобы было легко понять.

EDIT: Вот один пример узла XML:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?> 
<FUNDDATA> 
    <FUND_DATA> 
    <ADVISOR_FUND_CUSIP>316146703</ADVISOR_FUND_CUSIP> 
    <ADVISOR_FUND_ID>01118</ADVISOR_FUND_ID> 
    <ADVISOR_FUND_NAME>Pizza Fund - Class A</ADVISOR_FUND_NAME> 
    <ADVISOR_FUND_SASID>01118</ADVISOR_FUND_SASID> 
    <ALL_ADVISOR_CLASSES>01118,01123,01124,01125,01126</ALL_ADVISOR_CLASSES> 
    <ALL_ADVISOR_CLASSES_CUSIPS>316146703,316146885,316146877,316146802,316146869</ALL_ADVISOR_CLASSES_CUSIPS> 
    <ALL_ADVISOR_CLASSES_SASIDS>01118,01123,01124,01125,01126</ALL_ADVISOR_CLASSES_SASIDS> 
    <ALL_ADVISOR_CLASSES_TYPES>A,B,C,T,I</ALL_ADVISOR_CLASSES_TYPES> 
    <ALL_RETAIL_CLASSES>00026</ALL_RETAIL_CLASSES> 
    <ALL_RETAIL_CLASSES_CUSIPS>316146109</ALL_RETAIL_CLASSES_CUSIPS> 
    <ALL_RETAIL_CLASSES_SASIDS>00026</ALL_RETAIL_CLASSES_SASIDS> 
    <ALL_RETAIL_CLASSES_TYPES>N</ALL_RETAIL_CLASSES_TYPES> 
    <BUSINESS_UNIT>CCC</BUSINESS_UNIT> 
    <DATE_ID>September 2000</DATE_ID> 
    <PRIMARY_FUND_ID>000044</PRIMARY_FUND_ID> 
    <RETAIL_FUND_CUSIP>44444</RETAIL_FUND_CUSIP> 
    <RETAIL_FUND_ID>00026</RETAIL_FUND_ID> 
    <RETAIL_FUND_NAME>Pizza Fund</RETAIL_FUND_NAME> 
    <RETAIL_FUND_SASID>00026</RETAIL_FUND_SASID> 
    <TRADE_SYMBOL>CCHCC</TRADE_SYMBOL> 
    </FUND_DATA> 
</FUNDDATA> 
+0

Отправьте пример своего XML. – nwk

+0

@ nwk, я редактировал сообщение, чтобы включить образец XML. Благодарю. – dbonneville

+1

Если вы не знали, обратите внимание, что [документация для XML :: Simple] (https://metacpan.org/module/XML::Simple) говорит: * «Использование этого модуля в новом коде рекомендуется использовать другие модули, которые обеспечивают более простые и последовательные интерфейсы. В частности, настоятельно рекомендуется использовать XML :: LibXML. Основными проблемами с этим модулем являются большое количество опций и произвольные способы взаимодействия этих параметров - часто с неожиданные результаты ». * Он искажает структуру XML несколькими способами, а« XMLin », за которым следует« XMLout », редко воспроизводит оригинал. – Borodin

ответ

1

Это только один из гадости, которые вы можете найти при использовании XML::Simple.

В этом случае есть решение: Вам необходимо включить the ForceArray option в вызове конструктора, например, так

my $xmltemp = XML::Simple->new(
    SuppressEmpty => 1, 
    ForceArray => 1, 
); 

документация имеет это сказать об этом

Этот параметр должен быть установлен до '1', чтобы вставлять вложенные элементы в , представленные в виде массивов, даже если есть только один.

Смежные вопросы