Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用以制表符分隔的文件在Perl中构建XML_Xml_Perl_Libxml2_Tab Delimited - Fatal编程技术网

使用以制表符分隔的文件在Perl中构建XML

使用以制表符分隔的文件在Perl中构建XML,xml,perl,libxml2,tab-delimited,Xml,Perl,Libxml2,Tab Delimited,我对Perl比较陌生。请检查我做错了什么 我有以下输入选项卡分隔的文件,需要构建为XML,“pin”号是唯一标识符。如果“Pin”匹配,则 在报告下填充并显示多个“费用” Reason1 Reason2 Reason3 Pin Name Zip Date Time data1 data2 data3 Pin 1 data5 data6 data7 data8 data1 data2 data3 Pin 1 data5 data6

我对Perl比较陌生。请检查我做错了什么

我有以下输入选项卡分隔的文件,需要构建为XML,“pin”号是唯一标识符。如果“Pin”匹配,则 在报告下填充并显示多个“费用”

Reason1 Reason2 Reason3 Pin Name    Zip Date    Time

data1   data2   data3   Pin 1   data5   data6   data7   data8
data1   data2   data3   Pin 1   data5   data6   data9   data10
data1   data2   data3   Pin 1   data5   data6   data11  data12
我希望它构建以下XML

<XML_FILE>
  <REPORT TYPE="AB">
    <REASON1>data1</REASON>
    <REASON2>data2</REASON2>
    <REASON3>data3</REASON3>
    <PERSON>
      <PIN>Pin 1</PIN>
      <NAME>data5</NAME>
      <ZIP>data6<ZIP>
    </PERSON>
    <CHARGE>
      <DATE>data7</DATE>
      <TIME>data8</TIME>
    </CHARGE>
    <CHARGE>
       <DATE>data9</DATE>
       <TIME>data10<TIME>
    </CHARGE>
    <CHARGE>
       <DATE>data11</DATE>
       <TIME>data12</TIME>
    </CHARGE>
  </REPORT>
</XML_FILE>


use strict;
use XML::LibXML;

my $READFILENAME = "SomeDir\\data.txt";
my $WRITEFILENAME = "SomeDir\\test.xml";

my $doc = XML::LibXML::Document->new('1.0');
my $root = $doc->createElement("XML_FILE");
open (FILEWRITE, ">$WRITEFILENAME");
open (READFILE, $READFILENAME);
my $copy_person_pin = "XX";
foreach (<READFILE>) {
    my $line = $_; chomp $line;
    my @data = split(/\t/,$line);
    my $reason1 = $data[0];
    my $reason2 = $data[1];
    my $reason3 = $data[2];
    my $person_pin = $data[3];
    my $name = $data[4];
    my $zip = $data[5];
    my $date = $data[6];
    my $time = $data[7];
    my $report = $doc->createElement("REPORT");
    if ($person_pin ne $copy_person_pin)
    {  
      # Build the Report tags
      # I had to put $report out of if loop so that $report is avalible in else statement
      # my $report = $doc->createElement("REPORT");
      $report->setAttribute('TYPE'=>'AB');
      my @sortedReportTag = qw ( REASON1
                REASON2
                REASON3
                ); 

      my %reportHashTags;
      @reportHashTags { @sortedReportTag } = ($reason1,
                     $reason2,
                     $reason3
                         );                                                                            
      buildXMLElements(\@sortedReportTag, \%reportHashTags, $report); 

      $root-> appendChild($report);

      # Build the element for Person Tag
      my $person = $doc->createElement("PERSON");
      my @sortedPersonTag = qw ( PIN
                NAME
                ZIP); 
      my %personHashTags;
      @personHashTags { @sortedPersonTag } = ($person_pin,
                     $name,
                     $zip
                         );
      # Build the elements for Person Tag                                        
      buildXMLElements(\@sortedPersonTag, \%personHashTags, $person);
      $report-> appendChild($person); 


      # Build the elements for Charge Tag
      my $charge = $doc->createElement("CHARGE");     
      my @sortedChargeTag = qw ( DATE
                TIME
                );
      my %chargeHashTags;
      @chargeHashTags { @sortedChargeTag } = ($date,
                     $time
                      );  
      # Build the elements for Charge Tag                                     
      buildXMLElements(\@sortedChargeTag, \%chargeHashTags, $charge);
      $report-> appendChild($charge);
      $copy_person_pin = $person_pin;
    }
    else {
      my $charge = $doc->createElement("CHARGE");     
      my @sortedChargeTag = qw ( DATE
                TIME
                );
      my %chargeHashTags;
      @chargeHashTags { @sortedChargeTag } = ($date,
                     $time
                      );  
      # Build the elements for Charge Tag                                     
      buildXMLElements(\@sortedChargeTag, \%chargeHashTags, $charge);
      $report-> appendChild($charge); 
    }
}

$doc->setDocumentElement($root);

# Write the XML to a file
print FILEWRITE ($doc->toString());
close FILEWRITE;

sub buildXMLElements() {
  my($elementTags, $hashTags, $parentElement) = @_;
  for my $name (@$elementTags) {
    my $reportTag = $doc->createElement($name);
    my $reportValue = $hashTags->{$name};
    $reportTag->appendTextNode($reportValue);
    $parentElement->appendChild($reportTag);
  }
}

数据1
数据2
数据3
引脚1
数据5
数据6
数据7
数据8
数据9
数据10
数据11
数据12
严格使用;
使用XML::LibXML;
my$READFILENAME=“SomeDir\\data.txt”;
my$WRITEFILENAME=“SomeDir\\test.xml”;
我的$doc=XML::LibXML::Document->new('1.0');
my$root=$doc->createElement(“XML_文件”);
打开(文件写入,“>$WRITEFILENAME”);
打开(READFILE,$READFILENAME);
我的$copy\u person\u pin=“XX”;
foreach(){
my$line=$\uuUmp$line;
my@data=split(/\t/,$line);
my$reason1=$data[0];
my$reason2=$data[1];
my$reason3=$data[2];
我的$person_pin=$data[3];
我的$name=$data[4];
my$zip=$data[5];
my$date=$data[6];
my$time=$data[7];
my$report=$doc->createElement(“报告”);
如果($person\u pin ne$copy\u person\u pin)
{  
#构建报告标签
#我不得不把$report从if循环中去掉,这样$report就可以在else语句中使用
#my$report=$doc->createElement(“报告”);
$report->setAttribute('TYPE'=>'AB');
my@sortedReportTag=qw(原因1
理由2
理由3
); 
我的%reportHashTags;
@reportHashTags{@sortedReportTag}=($reason1,
$2,
$3
);                                                                            
buildXMLElements(\@sortedReportTag,\%reportHashTags,$report);
$root->appendChild($report);
#为Person标记构建元素
我的$person=$doc->createElement(“person”);
my@sortedPersonTag=qw(PIN码
名称
拉链);
我的%personHashTags;
@personHashTags{@sortedPersonTag}=($person\u pin,
$name,
$zip
);
#构建Person标记的元素
buildXMLElements(\@sortedPersonTag,\%personHashTags,$person);
$report->appendChild($person);
#构建电荷标签的元素
我的$charge=$doc->createElement(“费用”);
my@sortedChargeTag=qw(日期
时间
);
我的%chargeHashTags;
@chargeHashTags{@sortedChargeTag}=($date,
$time
);  
#构建电荷标签的元素
buildXMLElements(\@sortedChargeTag,\%chargeHashTags,$charge);
$report->appendChild($charge);
$copy\u person\u pin=$person\u pin;
}
否则{
我的$charge=$doc->createElement(“费用”);
my@sortedChargeTag=qw(日期
时间
);
我的%chargeHashTags;
@chargeHashTags{@sortedChargeTag}=($date,
$time
);  
#构建电荷标签的元素
buildXMLElements(\@sortedChargeTag,\%chargeHashTags,$charge);
$report->appendChild($charge);
}
}
$doc->setDocumentElement($root);
#将XML写入文件
打印文件写入($doc->toString());
关闭文件写入;
子构建XMLElements(){
my($elementTags、$hashTags、$parentElement)=@;
对于我的$name(@$elementTags){
my$reportTag=$doc->createElement($name);
my$reportValue=$hashTags->{$name};
$reportTag->appendTextNode($reportValue);
$parentElement->appendChild($reportTag);
}
}
我得到的结果是,基本上只有第一个“电荷”出现,而不是另外两个

<XML_FILE>
 <REPORT TYPE="AB">
   <REASON1>data1</REASON>
   <REASON2>data2</REASON2>
   <REASON3>data3</REASON3>
   <PERSON>
    <PIN>Pin 1</PIN>
    <NAME>data5</NAME>
    <ZIP>data6<ZIP>
   </PERSON>
   <CHARGE>
    <DATE>data7</DATE>
    <TIME>data8</TIME>
   </CHARGE>
  </REPORT>
   </XML_FILE>

数据1
数据2
数据3
引脚1
数据5
数据6
数据7
数据8
@史蒂文谢谢你的回复。但它不起作用。如果我按照建议在开头声明空$report,那么脚本将运行,但它仍然不会添加第二个和第三个费用。它仍然具有与上面相同的输出

  • 问题是在
    else
    块中
    $report
    是新创建的 未添加到
    $root
    的元素
  • 你应该做什么 是重用现有的
    $report
    元素,而不是创建新的 一个
因此,我将修改您的代码如下:

use strict;
use warnings;
use XML::LibXML;

my $READFILENAME = "data.txt";
my $WRITEFILENAME = "test.xml";

my $doc = XML::LibXML::Document->new('1.0');
my $root = $doc->createElement("XML_FILE");
open my $FILEWRITE, '>', $WRITEFILENAME;
open my $READFILE, '<', $READFILENAME;
my $copy_person_pin = "XX";
my $report;
while (my $line = <$READFILE>) {
    chomp $line;
    my @data = split(/\s+/,$line);
    my $reason1 = $data[0];
    my $reason2 = $data[1];
    my $reason3 = $data[2];
    my $person_pin = $data[3];
    my $name = $data[4];
    my $zip = $data[5];
    my $date = $data[6];
    my $time = $data[7];

    if ($person_pin ne $copy_person_pin)
    {  
        $report = $doc->createElement("REPORT");
        # Build the Report tags
        # I had to put $report out of if loop so that $report is avalible in else statement
        # my $report = $doc->createElement("REPORT");
        $report->setAttribute('TYPE'=>'AB');
        my @sortedReportTag = qw ( REASON1
                  REASON2
                  REASON3
                  ); 

        my %reportHashTags;
        @reportHashTags { @sortedReportTag } = ($reason1,
                       $reason2,
                       $reason3
                           );                                                                            
        buildXMLElements(\@sortedReportTag, \%reportHashTags, $report); 

        $root-> appendChild($report);

        # Build the element for Person Tag
        my $person = $doc->createElement("PERSON");
        my @sortedPersonTag = qw ( PIN
                  NAME
                  ZIP); 
        my %personHashTags;
        @personHashTags { @sortedPersonTag } = ($person_pin,
                       $name,
                       $zip
                           );
        # Build the elements for Person Tag                                        
        buildXMLElements(\@sortedPersonTag, \%personHashTags, $person);
        $report-> appendChild($person); 


        # Build the elements for Charge Tag
        my $charge = $doc->createElement("CHARGE");     
        my @sortedChargeTag = qw ( DATE
                  TIME
                  );
        my %chargeHashTags;
        @chargeHashTags { @sortedChargeTag } = ($date,
                       $time
                        );  
        # Build the elements for Charge Tag                                     
        buildXMLElements(\@sortedChargeTag, \%chargeHashTags, $charge);
        $report-> appendChild($charge);
        $copy_person_pin = $person_pin;
    }
    else {
        my $charge = $doc->createElement("CHARGE");     
        my @sortedChargeTag = qw ( DATE
                  TIME
                  );
        my %chargeHashTags;
        @chargeHashTags { @sortedChargeTag } = ($date,
                       $time
                        );  
        # Build the elements for Charge Tag                                     
        buildXMLElements(\@sortedChargeTag, \%chargeHashTags, $charge);
        $report-> appendChild($charge); 
    }
}

$doc->setDocumentElement($root);

# Write the XML to a file
print $FILEWRITE ($doc->toString());
close $FILEWRITE;

sub buildXMLElements {
  my($elementTags, $hashTags, $parentElement) = @_;
  for my $name (@$elementTags) {
    my $reportTag = $doc->createElement($name);
    my $reportValue = $hashTags->{$name};
    $reportTag->appendTextNode($reportValue);
    $parentElement->appendChild($reportTag);
  }
}
使用严格;
使用警告;
使用XML::LibXML;
我的$READFILENAME=“data.txt”;
my$WRITEFILENAME=“test.xml”;
我的$doc=XML::LibXML::Document->new('1.0');
my$root=$doc->createElement(“XML_文件”);
打开我的$FILEWRITE,'>',$WRITEFILENAME;

打开我的$READFILE,'如果要逐行处理文件,请不要含糊其辞。读入要使用的变量。当然,还要使用词法文件句柄
while(my$line=){chomp$line;…}
谢谢!我将把for循环改为while循环另一个Perl提示:
使用警告
,并从子例程声明中删除
()
。它们不像其他语言那样指定参数,而是“让您定义像内置函数一样工作的子程序”。谢谢!将合并这两个建议。我添加了适用于meGreat的完整代码!谢谢你,史蒂文,它能煮。谢谢你的努力……我投票赞成你的答案:)