转储XML文件元素和属性

时间:2016-07-22 10:53:13

标签: xml perl xml-parsing xml-libxml

我想从XML文件中打印所有元素及其属性名称和值。

<UTILITYBILLS>
  <BillingMessage>Bill Message TEST</BillingMessage>
  <StubMessage>Stub Message TEST</StubMessage>
  <PaymentCodeID>34</PaymentCodeID>
  <DueDate>08/01/2016</DueDate>
  <ScheduledPrintDate>07/04/2016</ScheduledPrintDate>
  <ActualPrintDate>07/07/2016</ActualPrintDate>
  <ActualPrintTime>9:37 AM</ActualPrintTime>
  <BILL AccountNumber="0390124-000" AccountType="Mayesville- Residential" UtilityAccountID="14242">
    <ConsumptionHistory>dfgdfg</ConsumptionHistory>
    <SERVICE Service=""/>
    <BILLINGITEMS BillingItemCode=""/>
    <CHARGES ChargeCategoryDescription="MAYESEVILLE CHARGES" Amount="70.09" Parent="1"/>
    <CHARGES ChargeCategoryDescription="MA - WATER" Amount="43.04" Parent="0">
      <LineItemDetail UtilityTransDetailID="6605683" ComponentType="Flat Rate" ComponentDescription="WATER MIN"/>
      <LineItemDetail UtilityTransDetailID="6606886" ComponentType="Block Rate" ComponentDescription="WATER CONS">
        <LIDetailConsumption MeterNumber="36313595" MeterType="Water &amp; Sewer 9" ServiceClassCode="Water &amp; Sewer" MeasurementTypeSequence="1"/>
      </LineItemDetail>
      <LineItemDetail UtilityTransDetailID="6606890" ComponentType="Block Rate" ComponentDescription="WATER CONS">
        <LIDetailConsumption MeterNumber="36313595" MeterType="Water &amp; Sewer 9" ServiceClassCode="Water &amp; Sewer" MeasurementTypeSequence="1"/>
      </LineItemDetail>
    </CHARGES>
    <CHARGES ChargeCategoryDescription="MA - SEWER" Amount="27.05" Parent="0">
      <LineItemDetail UtilityTransDetailID="6605685" ComponentType="Flat Rate" ComponentDescription="SEWER MINIMUM"/>
      <LineItemDetail UtilityTransDetailID="6606894" ComponentType="Block Rate" ComponentDescription="SEWER CONS">
        <LIDetailConsumption MeterNumber="36313595" MeterType="Water &amp; Sewer 9" ServiceClassCode="Water &amp; Sewer" MeasurementTypeSequence="1"/>
      </LineItemDetail>
    </CHARGES>
    <CONSUMPTION ServiceClass="Water &amp; Sewer" MeterType="Water &amp; Sewer 9" MeterNumber="36313595"/>
  </BILL>
  <BILL AccountNumber="0390124-000" AccountType="Mayesville- Residential" UtilityAccountID="14242">
    <ConsumptionHistory>dfgdfg</ConsumptionHistory>
    <SERVICE Service=""/>
    <BILLINGITEMS BillingItemCode=""/>
    <CHARGES ChargeCategoryDescription="MAYESEVILLE CHARGES" Amount="70.09" Parent="1"/>
    <CHARGES ChargeCategoryDescription="MA - WATER" Amount="43.04" Parent="0">
      <LineItemDetail UtilityTransDetailID="6605683" ComponentType="Flat Rate" ComponentDescription="WATER MIN"/>
      <LineItemDetail UtilityTransDetailID="6606886" ComponentType="Block Rate" ComponentDescription="WATER CONS">
        <LIDetailConsumption MeterNumber="36313595" MeterType="Water &amp; Sewer 9" ServiceClassCode="Water &amp; Sewer" MeasurementTypeSequence="1"/>
      </LineItemDetail>
      <LineItemDetail UtilityTransDetailID="6606890" ComponentType="Block Rate" ComponentDescription="WATER CONS">
        <LIDetailConsumption MeterNumber="36313595" MeterType="Water &amp; Sewer 9" ServiceClassCode="Water &amp; Sewer" MeasurementTypeSequence="1"/>
      </LineItemDetail>
    </CHARGES>
    <CHARGES ChargeCategoryDescription="MA - SEWER" Amount="27.05" Parent="0">
      <LineItemDetail UtilityTransDetailID="6605685" ComponentType="Flat Rate" ComponentDescription="SEWER MINIMUM"/>
      <LineItemDetail UtilityTransDetailID="6606894" ComponentType="Block Rate" ComponentDescription="SEWER CONS">
        <LIDetailConsumption MeterNumber="36313595" MeterType="Water &amp; Sewer 9" ServiceClassCode="Water &amp; Sewer" MeasurementTypeSequence="1"/>
      </LineItemDetail>
    </CHARGES>
    <CONSUMPTION ServiceClass="Water &amp; Sewer" MeterType="Water &amp; Sewer 9" MeterNumber="36313595"/>
  </BILL>
  <BILL AccountNumber="0390124-000" AccountType="Mayesville- Residential" UtilityAccountID="14242">
    <ConsumptionHistory>dfgdfg</ConsumptionHistory>
    <SERVICE Service=""/>
    <BILLINGITEMS BillingItemCode=""/>
    <CHARGES ChargeCategoryDescription="MAYESEVILLE CHARGES" Amount="70.09" Parent="1"/>
    <CHARGES ChargeCategoryDescription="MA - WATER" Amount="43.04" Parent="0">
      <LineItemDetail UtilityTransDetailID="6605683" ComponentType="Flat Rate" ComponentDescription="WATER MIN"/>
      <LineItemDetail UtilityTransDetailID="6606886" ComponentType="Block Rate" ComponentDescription="WATER CONS">
        <LIDetailConsumption MeterNumber="36313595" MeterType="Water &amp; Sewer 9" ServiceClassCode="Water &amp; Sewer" MeasurementTypeSequence="1"/>
      </LineItemDetail>
      <LineItemDetail UtilityTransDetailID="6606890" ComponentType="Block Rate" ComponentDescription="WATER CONS">
        <LIDetailConsumption MeterNumber="36313595" MeterType="Water &amp; Sewer 9" ServiceClassCode="Water &amp; Sewer" MeasurementTypeSequence="1"/>
      </LineItemDetail>
    </CHARGES>
    <CHARGES ChargeCategoryDescription="MA - SEWER" Amount="27.05" Parent="0">
      <LineItemDetail UtilityTransDetailID="6605685" ComponentType="Flat Rate" ComponentDescription="SEWER MINIMUM"/>
      <LineItemDetail UtilityTransDetailID="6606894" ComponentType="Block Rate" ComponentDescription="SEWER CONS">
        <LIDetailConsumption MeterNumber="36313595" MeterType="Water &amp; Sewer 9" ServiceClassCode="Water &amp; Sewer" MeasurementTypeSequence="1"/>
      </LineItemDetail>
    </CHARGES>
    <CONSUMPTION ServiceClass="Water &amp; Sewer" MeterType="Water &amp; Sewer 9" MeterNumber="36313595"/>
  </BILL>
</UTILITYBILLS>

上面的文件是sample.xml我试图获取每个元素,它的值以及每个子和子子及其值。

这是我的代码。

use XML::LibXML;

my $file   = "sample.xml";
my $parser = XML::LibXML->new();
my $xmldoc = $parser->parse_file($file);

for my $sample ( $xmldoc->getElementsByTagName('UTILITYBILLS') ) {

    for my $property ( $sample->findnodes('./*') ) {

        print OUT $property->nodeName(), ": ", $property->textContent(), "\n";

        my @attributeslist = $property->attributes();

        foreach my $value (@attributeslist) {
            my $string = $value->getValue();
            print OUT $value->nodeName(), ": ", "$string", "\n";
        }
    }
}

我的代码输出如下:

BillingMessage: Bill Message TEST
StubMessage: Stub Message TEST
PaymentCodeID: 34
DueDate: 08/01/2016
ScheduledPrintDate: 07/04/2016
ActualPrintDate: 07/07/2016
ActualPrintTime: 9:37 AM
BILL: 
    dfgdfg     



AccountNumber: 0390124-000
AccountType: Mayesville- Residential
UtilityAccountID: 14242
BILL: 
    dfgdfg     



AccountNumber: 0390124-000
AccountType: Mayesville- Residential
UtilityAccountID: 14242
BILL: 
    dfgdfg     



AccountNumber: 0390124-000
AccountType: Mayesville- Residential
UtilityAccountID: 14242

我希望输出如下

BillingMessage: Bill Message TEST
StubMessage: Stub Message TEST
PaymentCodeID: 34
DueDate: 08/01/2016
ScheduledPrintDate: 07/04/2016
ActualPrintDate: 07/07/2016
ActualPrintTime: 9:37 AM
BILL: 
ConsumptionHistory: dfgdfg  
AccountNumber: 0390124-000
AccountType: Mayesville- Residential
UtilityAccountID: 14242
And all sub child attributes and it's value
.
.
.

BillingMessage: Bill Message TEST
StubMessage: Stub Message TEST
PaymentCodeID: 34
DueDate: 08/01/2016
ScheduledPrintDate: 07/04/2016
ActualPrintDate: 07/07/2016
ActualPrintTime: 9:37 AM
BILL: 
    ConsumptionHistory: dfgdfg 
AccountNumber: 0390124-000
AccountType: Mayesville- Residential
UtilityAccountID: 14242
And all sub child attributes and it's value
.
.
.

请帮我解决这个问题。

1 个答案:

答案 0 :(得分:0)

只需转储所有节点名称及其值,这是一个奇怪的要求。你失去了所有的关系信息,但是,如果这就是你想要的那样

问题是textContent返回所有后代文本节点而不仅仅是直接子文本节点

我认为这可以做你想要的事情

use strict;
use warnings 'all';

use XML::LibXML;

my $file = 'UTILITYBILLS.xml';

my $doc = XML::LibXML->load_xml( location => $file );

for my $bill ($doc->findnodes('/UTILITYBILLS/BILL')) {

    for my $property ( $bill->findnodes('.//*') ) {

        printf "%s:\n", $property->nodeName;

        for my $text ( $property->findnodes('text()') ) {
            $text = $text->data =~ s/\A\s+|\s+\z//gr;
            print "    $text\n" if $text;
        }

        for my $attr ( $property->attributes ) {
            printf qq{    %s="%s"\n}, $attr->nodeName, $attr->value;
        }      
    }

    print "\n\n";
}

输出

ConsumptionHistory:
    dfgdfg
SERVICE:
    Service=""
BILLINGITEMS:
    BillingItemCode=""
CHARGES:
    ChargeCategoryDescription="MAYESEVILLE CHARGES"
    Amount="70.09"
    Parent="1"
CHARGES:
    ChargeCategoryDescription="MA - WATER"
    Amount="43.04"
    Parent="0"
LineItemDetail:
    UtilityTransDetailID="6605683"
    ComponentType="Flat Rate"
    ComponentDescription="WATER MIN"
LineItemDetail:
    UtilityTransDetailID="6606886"
    ComponentType="Block Rate"
    ComponentDescription="WATER CONS"
LIDetailConsumption:
    MeterNumber="36313595"
    MeterType="Water & Sewer 9"
    ServiceClassCode="Water & Sewer"
    MeasurementTypeSequence="1"
LineItemDetail:
    UtilityTransDetailID="6606890"
    ComponentType="Block Rate"
    ComponentDescription="WATER CONS"
LIDetailConsumption:
    MeterNumber="36313595"
    MeterType="Water & Sewer 9"
    ServiceClassCode="Water & Sewer"
    MeasurementTypeSequence="1"
CHARGES:
    ChargeCategoryDescription="MA - SEWER"
    Amount="27.05"
    Parent="0"
LineItemDetail:
    UtilityTransDetailID="6605685"
    ComponentType="Flat Rate"
    ComponentDescription="SEWER MINIMUM"
LineItemDetail:
    UtilityTransDetailID="6606894"
    ComponentType="Block Rate"
    ComponentDescription="SEWER CONS"
LIDetailConsumption:
    MeterNumber="36313595"
    MeterType="Water & Sewer 9"
    ServiceClassCode="Water & Sewer"
    MeasurementTypeSequence="1"
CONSUMPTION:
    ServiceClass="Water & Sewer"
    MeterType="Water & Sewer 9"
    MeterNumber="36313595"


ConsumptionHistory:
    dfgdfg
SERVICE:
    Service=""
BILLINGITEMS:
    BillingItemCode=""
CHARGES:
    ChargeCategoryDescription="MAYESEVILLE CHARGES"
    Amount="70.09"
    Parent="1"
CHARGES:
    ChargeCategoryDescription="MA - WATER"
    Amount="43.04"
    Parent="0"
LineItemDetail:
    UtilityTransDetailID="6605683"
    ComponentType="Flat Rate"
    ComponentDescription="WATER MIN"
LineItemDetail:
    UtilityTransDetailID="6606886"
    ComponentType="Block Rate"
    ComponentDescription="WATER CONS"
LIDetailConsumption:
    MeterNumber="36313595"
    MeterType="Water & Sewer 9"
    ServiceClassCode="Water & Sewer"
    MeasurementTypeSequence="1"
LineItemDetail:
    UtilityTransDetailID="6606890"
    ComponentType="Block Rate"
    ComponentDescription="WATER CONS"
LIDetailConsumption:
    MeterNumber="36313595"
    MeterType="Water & Sewer 9"
    ServiceClassCode="Water & Sewer"
    MeasurementTypeSequence="1"
CHARGES:
    ChargeCategoryDescription="MA - SEWER"
    Amount="27.05"
    Parent="0"
LineItemDetail:
    UtilityTransDetailID="6605685"
    ComponentType="Flat Rate"
    ComponentDescription="SEWER MINIMUM"
LineItemDetail:
    UtilityTransDetailID="6606894"
    ComponentType="Block Rate"
    ComponentDescription="SEWER CONS"
LIDetailConsumption:
    MeterNumber="36313595"
    MeterType="Water & Sewer 9"
    ServiceClassCode="Water & Sewer"
    MeasurementTypeSequence="1"
CONSUMPTION:
    ServiceClass="Water & Sewer"
    MeterType="Water & Sewer 9"
    MeterNumber="36313595"


ConsumptionHistory:
    dfgdfg
SERVICE:
    Service=""
BILLINGITEMS:
    BillingItemCode=""
CHARGES:
    ChargeCategoryDescription="MAYESEVILLE CHARGES"
    Amount="70.09"
    Parent="1"
CHARGES:
    ChargeCategoryDescription="MA - WATER"
    Amount="43.04"
    Parent="0"
LineItemDetail:
    UtilityTransDetailID="6605683"
    ComponentType="Flat Rate"
    ComponentDescription="WATER MIN"
LineItemDetail:
    UtilityTransDetailID="6606886"
    ComponentType="Block Rate"
    ComponentDescription="WATER CONS"
LIDetailConsumption:
    MeterNumber="36313595"
    MeterType="Water & Sewer 9"
    ServiceClassCode="Water & Sewer"
    MeasurementTypeSequence="1"
LineItemDetail:
    UtilityTransDetailID="6606890"
    ComponentType="Block Rate"
    ComponentDescription="WATER CONS"
LIDetailConsumption:
    MeterNumber="36313595"
    MeterType="Water & Sewer 9"
    ServiceClassCode="Water & Sewer"
    MeasurementTypeSequence="1"
CHARGES:
    ChargeCategoryDescription="MA - SEWER"
    Amount="27.05"
    Parent="0"
LineItemDetail:
    UtilityTransDetailID="6605685"
    ComponentType="Flat Rate"
    ComponentDescription="SEWER MINIMUM"
LineItemDetail:
    UtilityTransDetailID="6606894"
    ComponentType="Block Rate"
    ComponentDescription="SEWER CONS"
LIDetailConsumption:
    MeterNumber="36313595"
    MeterType="Water & Sewer 9"
    ServiceClassCode="Water & Sewer"
    MeasurementTypeSequence="1"
CONSUMPTION:
    ServiceClass="Water & Sewer"
    MeterType="Water & Sewer 9"
    MeterNumber="36313595"