首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在perl中依次打印XML标记的属性数据和标记值?

如何在perl中依次打印XML标记的属性数据和标记值?
EN

Stack Overflow用户
提问于 2016-07-08 12:41:37
回答 1查看 1.4K关注 0票数 1

假设我有一个XML文档示例,

代码语言:javascript
复制
<root>
    <subnode1 att1="sn1att1" att2="sn1att2">Subnode 1</subnode1>    
    <subnode2 att1="sn2att1" att2="sn2att2">Subnode 2</subnode2>
    <subnode3 att1="sn3att1" att2="sn3att2">
        <subnode31 att1="sn31att1" att2="sn31att2">
            <subnode311 att1="sn311att1" att2="sn311att2">
                <subnode3111 att1="sn3111att1" att2="sn3111att2">Subnode 3-111</subnode3111>
            </subnode311>
        </subnode31>
        <subnode32 att1="sn32att1" att2="sn32att2">Subnode 3-2</subnode32>
    </subnode3>
</root>

我想印这样的东西

代码语言:javascript
复制
sn1att1  sn1att2  Subnode 1
sn2att1  sn2att2  Subnode 2
sn3att1  sn3att2 
sn31att1  sn31att2 
sn311att1  sn311att2  
sn3111att1  sn3111att2  Subnode 3-111
sn32att1  sn32att2  Subnode 3-2

我编写了下面的代码,它能够打印所描述的属性,但无法打印标记值(例如"Subnode 1“、"Subnode 2”等)。

代码语言:javascript
复制
use XML::XPath;
use XML::XPath::XMLParser;

my $xp = XML::XPath->new( filename => 'raw1.xml' );

for my $node ( $xp->findnodes('*/*') ) {

    print "\n" . $node->getName . "\t";

    for my $attribute ( $node->getAttributes ) {
        print " " . $attribute->getData;
    }

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

        print "\n" . $property->getName . "\t";

        for my $attributes ( $property->getAttributes ) {
            print " " . $attributes->getData;
        }
    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-08 13:25:29

我觉得这能做你想要的

我对XML::XPath不太熟悉,但我认识XPath

看起来,对于XML中的每个元素,您希望打印一行,其中包含每个属性的值,如果有,则打印所有子文本节点的值。

这并不像看上去那么简单,因为任何元素都可能包含多个文本子元素,其中散布着多个子元素。

此代码将所有属性和所有非空白文本的值累加到数组@line中,如果结果不是空的,则打印行。

我不明白为什么您所需的输出不包括我的行

代码语言:javascript
复制
sn32att1 sn32att2 Subnode 3-2

也许你会解释?

代码语言:javascript
复制
use strict;
use warnings 'all';

use XML::XPath;

my $xp = XML::XPath->new( filename => 'raw1.xml' );

# for all elements in the data
#
for my $node ( $xp->findnodes('//*') ) {

    my @line;

    # all the attributes of this element
    #
    for my $attr ( $node->getAttributes ) {
        push @line, $attr->getData;
    }

    # and all the non-blank child text nodes of this element
    #
    for ( $node->findnodes('text()') ) {
        my $text = $_->getData;
        push @line, $text if $text =~ /\S/;
    }

    # print it if there's anything to print
    #
    print "@line\n" if @line;
}

输出

代码语言:javascript
复制
sn1att1 sn1att2 Subnode 1
sn2att1 sn2att2 Subnode 2
sn3att1 sn3att2
sn31att1 sn31att2
sn311att1 sn311att2
sn3111att1 sn3111att2 Subnode 3-111
sn32att1 sn32att2 Subnode 3-2
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38266974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档