【问题标题】:Dump XML file elements and attributes转储 XML 文件元素和属性
【发布时间】:2016-07-22 10:53:13
【问题描述】:

我想从 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
.
.
.

请帮我解决这个问题。

【问题讨论】:

    标签: xml perl xml-parsing xml-libxml


    【解决方案1】:

    只转储所有节点名称及其值是一个奇怪的要求。这样你会丢失所有的关系信息,但是如果你想要的话,嘿

    问题在于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"
    

    【讨论】:

    • 非常感谢您的帮助,但是有什么方法可以处理变量中的获取数据以单独使用,就像我的输出一样,第一个子元素将与每个账单信息重复。
    • @Paddy:我做了一些改变。这有帮助吗?
    • 在此更改程序中为 子标签工作并获取其节点名/元素和属性以及相应的值。实际上,我想重复以下 BillingMessage ...to... BILL: 部分与每个 BILL: 输出中显示的信息。
    猜你喜欢
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多