逐行拆分xml

时间:2012-05-13 05:15:45

标签: xml perl

我有一段xml代码,如下所示我会读到这个并用newline分割它

<head>
        <name>states.opml</name>
        <Created>Tue, 15 Mar 2005 16:35:45 GMT</Created>
        <Modified>Thu, 14 Jul 2005 23:41:05 GMT</Modified>
        <owner>Dave Winer</owner>
        <Email>dave@scripting.com</Email>
        <expansion>1, 6, 13, 16, 18, 20</expansion>
        <vertScrollState>1</vertScrollState>
        <windowTop>106</windowTop>
        <windowLeft>106</windowLeft>
        <windowBottom>558</windowBottom>
        <windowRight>479</windowRight>
        </head>

我的perl代码:

my $xml=<STDIN>;
my @head=split(/\n/,$xml);
print length(@head);
#output is 1...split is not working at all

我想要的是: 我想要的是这样的字符串数组:

@head={<head>,
        <name>states.opml</name>,
        <Created>Tue, 15 Mar 2005 16:35:45 GMT</Created>,
        <Modified>Thu, 14 Jul 2005 23:41:05 GMT</Modified>,
        <owner>Dave Winer</owner>,
        <Email>dave@scripting.com</Email>,
        <expansion>1, 6, 13, 16, 18, 20</expansion>,
        <vertScrollState>1</vertScrollState>,
        <windowTop>106</windowTop>,
        <windowLeft>106</windowLeft>,
        <windowBottom>558</windowBottom>,
        <windowRight>479</windowRight>,
        </head>}

有人可以帮忙吗?我知道XML :: XMLin,但不允许使用它。

谢谢!

2 个答案:

答案 0 :(得分:2)

实际上split正在按预期工作。您只需在$xml中读取一行,因此split只返回一行。如果你将文件放入标量$xml,那么你需要拆分,这段代码可以工作:

local $/ = undef;   # set input record separator to undef (instead of newline)
my $xml=<STDIN>;    # all lines are now in $xml
my @head=split(/\n/,$xml);    # so now we can split it

然而,这段代码并不符合你的想法:

print length(@head);

它打印数组大小的长度,即1. @head在标量上下文中作为字符串计算,字符串“1”的长度为1.您要查找的只是:

print scalar @head;

但为什么要去那么麻烦?只是做:

my @head = <STDIN>;   # all the lines are now in @head
print scalar @head;

如果您需要删除换行符,请使用chomp

chomp(my @head = <STDIN>);

答案 1 :(得分:1)

问题是网站上的文件具有旧版Mac OS编码,使用CR作为行分隔符。

输入记录分隔符 $/的正常设置会分隔LF个字符上的行,并且由于文件中没有,所以一次性读取所有内容。

解决此问题的传统方法是编写local $/ = "\r",之后CR个字符将终止同一作用域中的文件读取语句。此外,chomp会从该行的末尾删除CR

但是,如果您同时从多个文件中读取不同的行终止符,这可能会很麻烦,因为它会影响<FH>运算符而不会影响特定的文件句柄。

我遇到此问题的最佳方法是安装PerlIO::eol模块,该模块允许您使用MODE {{1}打开任何文件}。这会将所有不同的行终止符更改为标准<:raw:eol(LF),并且您的程序将独立于数据源而正常运行。

注意只需要安装模块 - 程序中不需要"\n"行。