2012-05-13 25 views
1

分割XML行我有一段XML代碼類似下面,我將在這個閱讀和換行符把它分解通過線

<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>[email protected]</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>[email protected]</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,但不允許使用它。

謝謝!

+3

爲什麼?如果你要處理XML,爲什麼不把它作爲XML來處理,而不是將它轉換成不同的格式,爲此你必須編寫一個解析器? – mirod

+1

@mirod是正確的。這個解決方案對源數據的改變非常脆弱。例如,XML規範中沒有任何內容阻止整個XML文件出現在單行上。 –

+0

似乎與某些類的任務類似。沒有實用的方法,只是測試基本技能 –

回答

1

的問題是,網站上的文件具有傳統的Mac OS編碼,它採用CR作爲行分隔符。

輸入記錄分隔符$/分離上LF字符線條的正常設置,因爲有沒有在你的文件,它是所有讀一次。

解決此問題的傳統方法是編寫local $/ = "\r",之後在同一範圍內的文件讀取語句將以CR字符終止。另外chomp將從行尾刪除CR

但是,如果您使用不同的行終止符從多個文件同時讀取,這會很尷尬,因爲它會影響<FH>運算符,而不是特定的文件句柄。

我所遇到對付這種情況的最巧妙的方法是安裝PerlIO::eol模塊,它可以讓你打開任何文件<:raw:eol(LF)一個MODE。這將所有不同的行結束符更改爲標準"\n",並且程序將獨立於數據源而正常運行。

注意該模塊只需要安裝 - 在程序中不需要use行。

+0

謝謝,現在它正確地分割成數組,但仍然無法打印到控制檯'local $/=「\ r」; my @ xml = ; print @xml; print「\ n」;'it give「 outline> ext =」Texas「/> co」/> a「/> created =」Tue,2005年7月12日23:56:47 GMT 「/> />」。那麼如何打印出這樣編碼的文件呢? – user1391821

+0

我仍然推薦使用'PerlIO :: eol',但如果你堅持修改'$ /',那麼你將不得不考慮'@ xml'中以'CR'而不是'LF'結尾的行。你可以通過編寫'local $/=「\ r」'chomp'並在每行之後添加'「\ n」'; my @ xml = ; chomp @xml;爲@xml打印「$ _ \ n」;'。但是對於模塊,您只需要'binmode STDIN':raw:eol(LF)'; my @ xml = ;打印@xml;'。 – Borodin

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>); 
+0

嗨,感謝您的幫助。我通過「$ ./read.pl user1391821

+0

對於問這樣一個愚蠢的問題感到抱歉。請幫忙...... – user1391821

+0

@ user1391821'keys'對於數組來說不是(真的),對於哈希來說。儘管它可以用於數組,以便在最新版本的perl中獲取其索引。您根本不需要循環,只需執行'print @ head',因爲print可以將列表作爲參數。如果你以前避免去掉換行符(用'chomp'或'split'),你會得到一個不錯的打印。 – TLP