
.asn1
(CDR 데이터)를 CSV로 변환하여 테이블에 로드하기 위한 몇 가지 제안을 찾고 있습니다 . 현재 접근 방식에 따라 Greenplum 테이블에 XSD 로드를 사용하는 대신 Informatica B2B 파서를 사용하여 ASN 파일을 XML로 구문 분석하고 있습니다.
나는 Perl이 이러한 작업을 더 나은 방식으로 수행할 수 있기를 바랍니다. 하루 동안 우리는 매우 큰 파일인 ~30,000개의 ASN 파일을 수신합니다.
XML을 CSV로 변환하려면(OS X에서 xmlstarlet을 사용하여 XML을 CSV로 변환하는 방법에 대해 혼란스러우신가요?) 이 접근 방식이 작동하는지 또는 Perl에 플러그인이 있는지 확실하지 않습니다.
ASN 파일은 바이너리 파일이고 두 번째 단계는 XML을 CSV로 변환하는 것입니다.
샘플 XML:
<?xml version="1.0" encoding="windows-1252"?>
<RadiusCDR_Parent>
<RadiusCDR>
<accountingRequest>
<userName>1200099344</userName>
<nasIPAddress>0A490010</nasIPAddress>
<nasPort>0</nasPort>
<serviceType>2</serviceType>
<framedProtocol>1</framedProtocol>
<framedIPAddress>64702E70</framedIPAddress>
<vendorSpecificExt>
<cisco>
<subAttributeID>1</subAttributeID>
<vendorLength>26</vendorLength>
<data>connect-progress=Call Up</data>
</cisco>
<cisco>
<subAttributeID>1</subAttributeID>
<vendorLength>19</vendorLength>
<data>portbundle=enable</data>
</cisco>
<cisco>
<subAttributeID>250</subAttributeID>
<vendorLength>17</vendorLength>
<data>S10.73.0.17:785</data>
</cisco>
<cisco>
<subAttributeID>253</subAttributeID>
<vendorLength>11</vendorLength>
<data>I0;153521</data>
</cisco>
<cisco>
<subAttributeID>253</subAttributeID>
<vendorLength>11</vendorLength>
<data>O0;559080</data>
</cisco>
</vendorSpecificExt>
<callingStationID>503c.c433.b8df</callingStationID>
<nasIdentifier>INMUNVMBXXXXNB0001AG3WAG001.ril.com</nasIdentifier>
<acctStatusType>3</acctStatusType>
<acctDelayTime>0</acctDelayTime>
<acctInputOctets>0257B1</acctInputOctets>
<acctOutputOctets>0887E8</acctOutputOctets>
<acctSessionID>009B51EC</acctSessionID>
<acctAuthentic>1</acctAuthentic>
<acctSessionTime>2012</acctSessionTime>
<acctInputPackets>1187</acctInputPackets>
<acctOutputPackets>1130</acctOutputPackets>
<eventTimeStamp>140E0A0F 123B0E</eventTimeStamp>
<nasPortType>5</nasPortType>
<nasPortID>0/0/0/902</nasPortID>
</accountingRequest>
</RadiusCDR>
<RadiusCDR_Parent>
Cisco 정보 이외의 나머지 정보도 모두 CSV로 저장하고 싶습니다.
답변1
을 사용하지 마십시오 XML::Simple
. 그것은나쁜 생각.
하지만 근본적으로 XML은 계층적 데이터 구조이고 CSV는 그렇지 않습니다. 결과적으로 일반적인 경우에 대한 번역을 해결하는 것은 불가능합니다.
그러나 표준 레코드 구조를 고려하면 그다지 어렵지 않습니다.
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
use Text::CSV;
use Data::Dumper;
my $twig = XML::Twig->new->parse( \*DATA );
#read heading from first record.
my @headings =
map { $_->tag } $twig->findnodes( '//accountingRequest', 0 )->children;
my $csv_out = Text::CSV->new( { binary => 1, eol => "\n" } );
$csv_out->print( \*STDOUT, \@headings );
foreach my $accountingRequest ( $twig->findnodes('//accountingRequest') ) {
my @row = map { $accountingRequest->first_child_text($_) } @headings;
$csv_out->print( \*STDOUT, \@row );
}
그러면 최상위 '태그'와 일치하는 값이 추출되어 인쇄됩니다.
하지만 완벽하지는 않습니다. 앞서 말했듯이 데이터는 계층적이기 때문입니다. cisco
레코드로 무엇을 할지 결정해야 하는 레코드가 있습니다 . 해당 레코드를 CSV에 어떻게 표시해야 합니까?
답변2
CSV와 다른 XML 파일 세트에 대해 아래 코드를 얻었습니다.
암호:
#!/usr/bin/perl
# Script to illustrate how to parse a simple XML file
# and pick out all the values for a specific element, in
# this case all the titles.
# use strict;
use XML::Simple;
use Data::Dumper;
# create object
$xml = new XML::Simple (KeyAttr=>[]);
# read XML file
$data = $xml->XMLin("test1.xml");
my $booklist = XMLin('test1.xml'); #booklist is the array
# print Dumper($booklist);
foreach my $FreemanFees (@{$booklist->{FreemanFees}}) {
print
$FreemanFees->{SdcLoanFacilityNumber} , "," ,
$FreemanFees->{DealId} ,",",
$FreemanFees->{Tranche}->{SdcDealNumber} , "," ,
$FreemanFees->{Tranche}->{ManagerFeeAndCredits}->{ManagerFeeAndCredit}->{FreemanFeesForManager}->{ManagerNumberForFreemanFee}, ",",
$FreemanFees->{Tranche}->{ManagerFeeAndCredits}->{ManagerFeeAndCredit}->{FreemanFeesForManager}->{currencyId},",",
$FreemanFees->{Tranche}->{ManagerFeeAndCredits}->{ManagerFeeAndCredit}->{FreemanFeesForManager}->{sdcCurrencyCode} , "," ,
$FreemanFees->{Tranche}->{ManagerFeeAndCredits}->{ManagerFeeAndCredit}->{FreemanFeesForManager}->{scale}, ",",
$FreemanFees->{Tranche}->{ManagerFeeAndCredits}->{ManagerFeeAndCredit}->{FreemanFeesForManager}->{content} , "," ,"\n" ;
}
하지만 더 많은 요소가 있는 경우 다음 요소를 가져오는 방법은 무엇입니까?