0

执行下面的代码(减去数据库调用)后,我收到“第 7 列第 331 行错误:文档末尾的额外内容”错误。我浏览了这些论坛,但找不到解决方案。我没有任何随机字符或任何应该添加额外空格的代码......有什么想法吗?

<?php 
header('Content-type: text/xml');
mysql_connect("localhost", "---", "---");
mysql_select_db("---");

$query = "SELECT title FROM table";
$result = mysql_query($query);

$xml = new XMLWriter();
$xml->openURI("php://output");
$xml->startDocument();
$xml->setIndent(true);
$xml->writeRaw('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">');
$xml->startElement('url');
while ($row = mysql_fetch_assoc($result)) {
    if(!empty($row)){
        $title = $row['title'];
        $xml->startElement('loc');
            $xml->writeRaw('http://domain.com/article/');
        $xml->endElement();
        $xml->startElement('news:news');
            $xml->startElement("news:publication");
                $xml->startElement("news:name");
                    $xml->writeRaw('Name');
                $xml->endElement();
                $xml->startElement("news:language");
                    $xml->writeRaw('en');
                $xml->endElement();
            $xml->endElement();
            $xml->startElement('news:title');
                $xml->writeRaw($title);
            $xml->endElement();
            $xml->endElement();
    }
}
$xml->endElement();
$xml->flush();
4

1 回答 1

3

编程中的一个关键点是降低某些代码的复杂性。这包括减少缩进,这样就不会有太多的代码相互粘连。这通常很难遵循。

例如,while 体内的 if 子句可以大大简化,将内部已经向上移动一级:

while ($row = mysql_fetch_assoc($result)) {

    if (empty($row)) {
        continue;
    }

    $title = $row['title'];
    ...
}

continue循环内部只是说:下一次迭代。

您创建的 XML 标记也有缩进。并非所有都可以预防,但是,有些可以。例如,该XMLWriter::writeElement()方法允许输出包含其内部文本的整个元素。这允许减少以下三行:

$xml->startElement('loc');
    $xml->writeRaw('http://domain.com/article/');
$xml->endElement();

对一个:

$xml->writeElement('loc', 'http://domain.com/article/');

由于有多组这样的行,现在的代码实际上已经很短了。通过结束文档也可以改善结尾,甚至不需要刷新。为了使缩进更具可读性,您还可以使用方括号来表示缩进:

while ($row = mysql_fetch_assoc($result)) {

    if (empty($row)) {
        continue;
    }

    $title = $row['title'];

    $xml->writeElement('loc', 'http://domain.com/article/');

    $xml->startElement('news:news');
    {
        $xml->startElement("news:publication");
        {
            $xml->writeElement("news:name", 'Name');
            $xml->writeElement("news:language", 'en');
        }
        $xml->endElement();

        $xml->writeElement('news:title', $title);
    }
    $xml->endElement();
}

$xml->endDocument();

所以这不仅更具可读性,好消息是你遇到错误的情况也得到了修复。那是因为该 XMLWriter::writeRaw()方法已被删除。它写原始文本的功能是什么,这意味着未转义:

$title = 'hackers <3 noodles';

$xml->startElement('news:title');
    $xml->writeRaw($title);
$xml->endElement();

输出:

<news:title>hackers <3 noodles</news:title>
                    ^

如输出所示,<字符逐字进入输出。根据标题,甚至可以注入纯 XML 代码,从而破坏整个文档结构并导致错误。使用XMLWriter::writeElement()对此免疫:

$title = 'hackers <3 noodles';

$xml->writeElement('news:title', $title);

输出:

<news:title>hackers &lt;3 noodles</news:title>
                    ^^^^

如输出所示,此处使用了属性 XML 实体来保留文档结构。

所以你最初寻找的方法是XMLWriter::text(). 但是对于这种情况,您不再需要它,因为优化后的代码不再存在该问题。所有文本输出都通过XMLReader::writeElement(). 另请参阅使用 PHP XMLWriter::writeElement 时保留 XML 代码,这与同一主题但相反。

我希望这对您仍然有用,因为问题有点老了。

于 2013-09-27T16:03:09.567 回答