执行下面的代码(减去数据库调用)后,我收到“第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();
答案 0 :(得分:3)
编程的一个关键点是降低某些代码的复杂性。这包括减少缩进,以便没有太多的代码插入彼此。这通常很难理解。
例如,while body中的if子句可以大大减少,内部已经向上移动了一个级别:
while ($row = mysql_fetch_assoc($result)) {
if (empty($row)) {
continue;
}
$title = $row['title'];
...
}
循环中的continue
只是说:下一次迭代。
您创建的XML标记也有缩进。然而,并非所有人都可以预防。例如,XMLWriter::writeElement()
方法允许输出包含其内部文本的whote元素。这允许减少以下三行:
$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 <3 noodles</news:title>
^^^^
正如输出所示,这里使用了有效的XML实体来保留文档结构。
因此,您最初寻找的方法是XMLWriter::text()
。但是对于这种情况你不再需要它,因为优化的代码不再具有这个问题了。所有文本输出都通过XMLReader::writeElement()
正确编码。另请参阅Retain XML code when using PHP XMLWriter::writeElement,它是关于同一主题但来自相反的主题。
我希望这对你来说仍然有用,因为这个问题有点老了。