2011-03-29 42 views
4

xml:19558:解析器錯誤:只允許在文檔開始時使用XML聲明問題 - 僅在文檔​​開始時允許XML聲明

任何解決方案?我使用php XMLReader來解析一個大的XML文件,但得到這個錯誤。我知道文件格式不正確,但我認爲它不可能通過該文件並刪除這些額外的聲明。所以任何想法,請幫助

+2

如果格式不正確,則不是XML。如果它不是XML,那麼XMLReader不會很好地播放。 – drudge 2011-03-29 22:11:07

+0

該文件的唯一問題是多個聲明:( (<?xml version =「1.0」encoding =「UTF-8」standalone =「no」?>) 反正出? – Aamir 2011-03-29 22:16:38

+0

需要刪除空格!如何識別和修復這樣的錯誤: https://www.youtube.com/watch?v=4jWhO07ICvw – 2016-11-28 13:44:15

回答

17

請確保在第一個標記之前沒有任何空格。 試試這個:

<?php 
//Declarations 
$file = "data.txt"; //The file to read from. 

#Read the file 
$fp = fopen($file, "r"); //Open the file 
$data = ""; //Initialize variable to contain the file's content 
while(!feof($fp)) //Loop through the file, read it till the end. 
{ 
    $data .= fgets($fp, 1024); //append next kb to data 
} 
fclose($fp); //Close file 
#End read file 
$split = preg_split('/(?<=<\/xml>)(?!$)/', $data); //Split each xml occurence into its own string 

foreach ($split as $sxml) //Loop through each xml string 
{ 
    //echo $sxml; 
    $reader = new XMLReader(); //Initialize the reader 
    $reader->xml($sxml) or die("File not found"); //open the current xml string 
    while($reader->read()) //Read it 
    { 
     switch($reader->nodeType) 
     { 
      case constant('XMLREADER::ELEMENT'): //Read element 
       if ($reader->name == 'record') 
       { 
        $dataa = $reader->readInnerXml(); //get contents for <record> tag. 
        echo $dataa; //Print it to screen. 
       } 
      break; 
     } 
    } 
    $reader->close(); //close reader 
} 
?> 

設置$文件變量所需的文件。注意我不知道這對於4GB文件有效。告訴我如果沒有。

編輯: 這是另一種解決方案,它應該更好地處理較大的文件(解析它在讀取文件時)。

<?php 
set_time_limit(0); 
//Declarations 
$file = "data.txt"; //The file to read from. 

#Read the file 
$fp = fopen($file, "r") or die("Couldn't Open"); //Open the file 

$FoundXmlTagStep = 0; 
$FoundEndXMLTagStep = 0; 
$curXML = ""; 
$firstXMLTagRead = false; 
while(!feof($fp)) //Loop through the file, read it till the end. 
{ 
    $data = fgets($fp, 2); 
    if ($FoundXmlTagStep==0 && $data == "<") 
     $FoundXmlTagStep=1; 
    else if ($FoundXmlTagStep==1 && $data == "x") 
     $FoundXmlTagStep=2; 
    else if ($FoundXmlTagStep==2 && $data == "m") 
     $FoundXmlTagStep=3; 
    else if ($FoundXmlTagStep==3 && $data == "l") 
    { 
     $FoundXmlTagStep=4; 
     $firstXMLTagRead = true; 
    } 
    else if ($FoundXmlTagStep!=4) 
     $FoundXmlTagStep=0; 

    if ($FoundXmlTagStep==4) 
    { 
     if ($firstXMLTagRead) 
     { 
      $firstXMLTagRead = false; 
      $curXML = "<xm"; 
     } 
     $curXML .= $data; 

     //Start trying to match end of xml 
     if ($FoundEndXMLTagStep==0 && $data == "<") 
      $FoundEndXMLTagStep=1; 
     elseif ($FoundEndXMLTagStep==1 && $data == "/") 
      $FoundEndXMLTagStep=2; 
     elseif ($FoundEndXMLTagStep==2 && $data == "x") 
      $FoundEndXMLTagStep=3; 
     elseif ($FoundEndXMLTagStep==3 && $data == "m") 
      $FoundEndXMLTagStep=4; 
     elseif ($FoundEndXMLTagStep==4 && $data == "l") 
      $FoundEndXMLTagStep=5; 
     elseif ($FoundEndXMLTagStep==5 && $data == ">") 
     { 
      $FoundEndXMLTagStep=0; 
      $FoundXmlTagStep=0; 
      #finished Reading XML 
      ParseXML ($curXML); 
     } 
     elseif ($FoundEndXMLTagStep!=5) 
      $FoundEndXMLTagStep=0; 
    } 
} 
fclose($fp); //Close file 
function ParseXML ($xml) 
{ 
    //echo $sxml; 
    $reader = new XMLReader(); //Initialize the reader 
    $reader->xml($xml) or die("File not found"); //open the current xml string 
    while($reader->read()) //Read it 
    { 
     switch($reader->nodeType) 
     { 
      case constant('XMLREADER::ELEMENT'): //Read element 
       if ($reader->name == 'record') 
       { 
        $dataa = $reader->readInnerXml(); //get contents for <record> tag. 
        echo $dataa; //Print it to screen. 
       } 
      break; 
     } 
    } 
    $reader->close(); //close reader 
} 
?> 
+0

沒有親愛的不是這種情況。actaully this line(<?xml version =「1.0」encoding =「UTF-8 「standalone =」no「?>)在文件中被重複多次..這就是錯誤報告所說的。 – Aamir 2011-03-29 22:12:14

+0

你有 Ben 2011-03-29 22:13:56

+0

yes,但它現在是多次,如何解決這個問題?有些東西就像刪除這些額外的標籤,但如何? – Aamir 2011-03-29 22:17:37

1

如果有多個XML聲明,你可能有很多的XML文件的串聯,也不止一個根元素。目前還不清楚你將如何有意義地解析它們。

儘量讓XML的源頭先給你真正的XML。如果這不起作用,請在分析之前查看是否可以執行一些預處理來修復XML。

+0

hmm ..請你讓我知道如何刪除這些額外的聲明?任何簡單的PHP代碼?其實我對這一切都很陌生,只是呆在這裏。 – Aamir 2011-03-29 22:15:24

+0

我知道你的意思是...! 儘量讓XML的源頭先給你真正的XML。 – Aamir 2011-03-29 22:15:42

+0

你從哪裏得到XML?您能否與負責生成XML的負責人交談,因爲這是不正確的,應該予以糾正。爲了修復XML,請查看PHP字符串替換。 – 2011-03-29 22:16:39

1

此問題的另一個可能的原因是unicode文件頭。 如果您的XML編碼爲UTF-8,則文件內容始終以這3個字節「EF BB BF」開頭。如果嘗試從字節數組轉換爲字符串,這些字節可能會被錯誤地解釋。 解決方案是直接將字節數組寫入文件,而無需從字節數組中讀取getString。

ASCII沒有文件頭 的Unicode:FF FE UTF-8:EF BB BF UTF-32:FF FE 00 00

只要打開在UltraEdit的文件,你可以看到這些字節。