2010-09-22 2 views
2

Учитывая, что XML :: Simple - единственный модуль, который можно использовать, я застрял в извлечении значений из XML. Структура опускается ниже:Как извлечь значения из XML-файла с помощью XML: Simple Perl?

<testxml> 
    <dev> 
     <A> 
      <tables> 
       <datatables> 
        <table>a1</table> 
        <table>a2</table> 
        <table>a3</table> 
       </datatables> 
       <propertytables> 
        <table>A1</table> 
        <table>A2</table> 
       </propertytables> 
      </tables> 
     </A> 
     <B> 
      <tables> 
       <datatables> 
        <table>b1</table> 
        <table>b2</table> 
       </datatables> 
       <propertytables> 
        <table>B1</table> 
        <table>B2</table> 
       </propertytables> 
      </tables> 
     </B> 
    </dev> 
</testxml> 

XMLout является:

<opt> 
    <dev name="A"> 
    <tables name="datatables"> 
     <table>a1</table> 
     <table>a2</table> 
     <table>a3</table> 
    </tables> 
    <tables name="propertytables"> 
     <table>A1</table> 
     <table>A2</table> 
    </tables> 
    </dev> 
    <dev name="B"> 
    <tables name="datatables"> 
     <table>b1</table> 
     <table>b2</table> 
    </tables> 
    <tables name="propertytables"> 
     <table>B1</table> 
     <table>B2</table> 
    </tables> 
    </dev> 
</opt> 

Как получить массив таблицы сказать, для этого условия:
имя DEV = "B" и таблицы имя = "propertytables" # для выхода В1, В2

+3

Почему это единственный модуль, который можно использовать? – Ether

+0

Мой босс говорит, что XPath или любой другой модуль просто избыточный, чтобы использовать в этом случае :( – Abhishek

+0

Итак, ваш босс скорее прочитал бы весь файл и создаст большую структуру данных в памяти? :) –

ответ

3

Неверно, что XML :: Simple является единственным модулем, который будет использоваться для этой роли. Для чего-то вроде этого я бы использовал XML :: LibXML с небольшим количеством XPath.

Но если вы хотите использовать XML :: Simple, то я считаю, что наилучшим подходом является использование Data :: Dumper, чтобы сбрасывать структуру данных, что XML :: Simple builds и использовать этот дамп для разработки наилучшего способа прогуляйтесь по структуре. В вашем случае это довольно просто.

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::Simple; 
use Data::Dumper; 

my $xml = do { local $/; <DATA> }; 

my $doc = XMLin($xml); 

# print Dumper $doc; 

my $dev = 'B'; 
my $table = 'propertytables'; 

foreach (@{$doc->{dev}{$dev}{tables}{$table}{table}}) { 
    print "$_\n"; 
} 

__END__ 
<opt> 
    <dev name="A"> 
    <tables name="datatables"> 
     <table>a1</table> 
     <table>a2</table> 
     <table>a3</table> 
    </tables> 
    <tables name="propertytables"> 
     <table>A1</table> 
     <table>A2</table> 
    </tables> 
    </dev> 
    <dev name="B"> 
    <tables name="datatables"> 
     <table>b1</table> 
     <table>b2</table> 
    </tables> 
    <tables name="propertytables"> 
     <table>B1</table> 
     <table>B2</table> 
    </tables> 
    </dev> 
</opt> 
+0

Как сделать силовое оружие на одном объекте? Я пытаюсь что-то вроде этого: например, если для dev «B», если «propertytables» имеет одну таблицу, он обрабатывается как скаляр. my $ config = XMLin ('./ test.xml', forcearray => ['{dev} -> {B} -> {tables} -> {propertytables} -> {table}']); Но я думаю, что это неправильный путь. – Abhishek

+0

О, я понял. Мне просто нужно указать forcearray => [qw (table)] – Abhishek

2
$ref->{dev}{B}{tables}{propertytables}{table} 

будет обращение и

@{ $ref->{dev}{B}{tables}{propertytables}{table} } 

будет в списке.

Но действительно

my $ref = XMLin($some_source); 
use Smart::Comments; 
### $ref 

# ... OR ... 

use Data::Dumper; 
print Data::Dumper->Dump([ $ref ], [ '*ref' ]); 

изучить структуру, чтобы увидеть, что Pathing будет.

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