2013-09-23 5 views
0

Я пытался выяснить, как получить XML-источник данных, обработанный в CSV-файл, и это заставляет меня немного сходить с ума. У меня есть источник данных, который мне нужен, чтобы проанализировать создание CSV. Я также должен иметь возможность включать идентификатор узла в качестве столбца. Вот что у меня есть:Perl XML to CSV Parse

  #!/usr/bin/perl 
      use warnings; 
     use strict; 
     use XML::XPath; 

     #Name of the CSV File 
     my $filename = "parse.csv"; 

     #Create the file. 
     open(INPUT,">$filename") or die "Cannot create file"; 

     #Collect the XML and set nodes 
     my($xp) = XML::XPath->new(join('', <DATA>)); 
     my(@records) = $xp->findnodes('/CATALOG/CD'); 
     my($firstTime) = 0; 

     #Loop through each record 
     foreach my $record (@records) { 
      my(@fields) = $xp->find('./child::*', $record)->get_nodelist(); 
      unless ($firstTime++) { 
      #Print Headers 
       print(join(',', map { $_->getName() } @fields), "\n"); 
      } 
      #Print Content 
       print(join(',', map { $_->string_value() } @fields), "\n"); 
     } 
     #Close the file. 
     close(INPUT); 


     __DATA__ 
     <FOOD> 
      <ITEM id='1'> 
       <Color>Brown</Color> 
       <Name>Steak</Name> 
      </ITEM> 
      <ITEM id='2'> 
       <Color>Blue</Color> 
       <Name>Blueberries</Name> 
      </ITEM> 
      <ITEM id='3'> 
       <Color>Red</Color> 
       <Name>Apple</Name> 
      </ITEM> 
     </FOOD> 

Он создает CSV, но его пустой & я думаю, что его из-за печати строк в цикле Еогеасп.

Любая помощь была бы принята с благодарностью!

+0

Как бы то ни было, не помещайте файлы в имена файлов в свои скрипты, если сможете их избежать. Предоставляя им необязательные аргументы, считывая ввод с '<>' (или делая эквивалент) и записывая вывод в 'STDOUT', ваши сценарии намного легче повторно использовать, комбинировать и тестировать. – reinierpost

ответ

2

Вы печатаете свои заголовки и контент на стандартный вывод, а не на свой выходной файл. Вам необходимо передать дескриптор файла в качестве первого аргумента в printбез запятую между ним и тем, что вы хотите распечатать. Что-то вроде: print FILE join(',', ...), "\n";

Я бы также рекомендовал не использовать INPUT в качестве дескриптора файла, который вы выводите, - это немного смущает понимание кода.

1

Учитывая простоту схемы XML, это легче сделать с AnyData

Например:

#!/usr/bin/perl 
# This script converts a XML file to CSV format. 

# Load the AnyData XML to CSV conversion modules 
use XML::Parser; 
use XML::Twig; 
use AnyData; 

my $input_xml = "test.xml"; 
my $output_csv = "test.csv"; 


$flags->{record_tag} = 'ITEM'; 
adConvert('XML', $input_xml, 'CSV', $output_csv, $flags); 

конвертировать бы структуру данных (XML) в:

id,Color,Name 
1,Brown,Steak 
2,Blue,Blueberries 
3,Red,Apple 
1

В вашем случае вы используете/CATALOG/CD, а не ваши данные. Пожалуйста, используйте что-то наподобие

my(@records) = $xp->findnodes('/FOOD/ITEM'); 
.... 
... 
... 
print INPUT (join(',', map { $_->getName() } @fields), "\n");