Php 问题-仅允许在文档开头使用XML声明

Php 问题-仅允许在文档开头使用XML声明,php,xml,xmlreader,Php,Xml,Xmlreader,xml:19558:解析器错误:仅允许在文档开头声明xml 有什么解决办法吗?我正在使用php XMLReader解析一个大的XML文件,但遇到了这个错误。我知道该文件的格式不好,但我认为不可能遍历该文件并删除这些额外的声明。因此,如果您有任何想法,请帮助确保第一个标记前没有任何空白。 试试这个: <?php //Declarations $file = "data.txt"; //The file to read from. #Read the file $fp = fopen

xml:19558:解析器错误:仅允许在文档开头声明xml


有什么解决办法吗?我正在使用php XMLReader解析一个大的XML文件,但遇到了这个错误。我知道该文件的格式不好,但我认为不可能遍历该文件并删除这些额外的声明。因此,如果您有任何想法,请帮助

确保第一个标记前没有任何空白。 试试这个:

    <?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
}
?>
(?!$)/,$数据)//将每个xml事件拆分为自己的字符串 foreach($sxml分割)//循环遍历每个xml字符串 { //echo$sxml; $reader=newXMLReader();//初始化读取器 $reader->xml($sxml)或die(“未找到文件”);//打开当前xml字符串 而($reader->read())//读取它 { 开关($reader->nodeType) { 大小写常量('XMLREADER::ELEMENT')://读取元素 如果($reader->name=='record') { $dataa=$reader->readInnerXml();//获取标记的内容。 echo$dataa;//将其打印到屏幕上。 } 打破 } } $reader->close();//关闭读取器 } ?> 将$file变量设置为所需的文件。注意,我不知道这对4gb文件的效果如何。如果没有,告诉我

编辑: 这是另一个解决方案,它应该可以更好地处理较大的文件(在读取文件时进行解析)

xml($xml)或die(“未找到文件”)//打开当前的xml字符串
而($reader->read())//读取它
{
开关($reader->nodeType)
{
大小写常量('XMLREADER::ELEMENT')://读取元素
如果($reader->name=='record')
{
$dataa=$reader->readInnerXml();//获取标记的内容。
echo$dataa;//将其打印到屏幕上。
}
打破
}
}
$reader->close()//近距离阅读
}
?>

如果您有多个XML声明,则可能有多个XML文件的串联,以及多个根元素。现在还不清楚如何有意义地解析它们


尽最大努力获取XML的源代码,以便首先为您提供真正的XML。如果这不起作用,请查看是否可以在解析XML之前进行一些预处理以修复它。

导致此问题的另一个可能原因是unicode文件头。 如果XML的编码是UTF-8,则文件内容将始终以这3个字节“EF-BB-BF”开头。如果试图从字节数组转换为字符串,这些字节可能会被错误地解释。 解决方案是直接将字节数组写入文件,而无需从字节数组读取getString

ASCII没有文件头 Unicode:FF FE UTF-8:EF BB高炉 UTF-32:FF FE 00


只需在ultraedit中打开文件,就可以看到这些字节。

如果格式不正确,则不是XML。如果不是XML,那么XMLReader就不能很好地发挥作用。该文件唯一的问题是多个声明:(()无论如何都要删除?需要删除空格!下面是如何发现和修复此类错误的视频:不,亲爱的,不是这样。实际上这行()在文件中多次重复..这是错误报告所说的。你有是的,但现在是多次了,如何解决问题?一些事情,如删除这些额外的标记,但如何???你可以在每次拆分字符串这是一个好主意,但有多贵?:(嗯……你能告诉我如何删除这些额外的声明吗?任何简单的php代码吗?事实上,我对所有这些都很陌生,只是停留在这里。我不明白你的意思…!努力获取XML的源代码,以便首先为你提供真正的XML。你从哪里获得XML?你能和负责生成XML的人bec谈谈吗因为这是不对的,应该纠正。要修复XML,请查看PHP字符串替换。给我们完整的XML文档和您拥有的PHP解析器。然后我们可以帮助更多@mazzzz确定,但我如何向您提供文件,大约4 GBs:(
<?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
}
?>