我正在尝试使用MediaWiki的API来获取XML格式的文章并将它们包含在我的页面上。我创建了一个简单的代码,它基本上使用?action=parse&page=Page_Name&format=xml
请求获取文章的XML表示。代码如下:
if($_GET["page"]=='') die("Page not specified (possibly direct call)");
$pagename = $_GET["page"];
$handle = @fopen("mediawiki/api.php?action=parse&page=".$pagename."&format=xml", "r");
if ($handle) {
while (!feof($handle)) {
$buffer = $buffer.fgets($handle);
}
$buffer = html_entity_decode($buffer);
/*
echo $buffer;
*/
$xml = simplexml_load_string($buffer);
foreach($xml->parse->children() as $child){
switch($child->getName()){
case "text":
echo $child->asXML()."<br/>";
break;
case "categories":
echo "<h3>Categories this project is related to: </h3><br/>";
foreach($child->children() as $grandChild){
echo $grandChild." | ";
}
break;
}
}
fclose($handle);
}
现在的问题是我的输出非常奇怪。任何<a name="" href=""></a>
都会转换为<a name="" href=""/>
,这会使所有后续文本成为一个链接(我猜是因为没有结束标记</a>
)。这在Mozilla Firefox和Google Chrome中都可以看到。我怀疑$buffer = html_entity_decode($buffer);
会导致这个问题。是否有html_entity_decode();
的参数我应该指定以避免这种情况?是由于我的代码中的html_entity_decode();
的其他错误或误用造成的吗?
(要查看Wiki API的XML输出,您可以尝试http://en.wikipedia.org/w/api.php?action=parse&page=No_Such_Page&format=xml
使用不同的page
参数
可能的解决方案:我不想像乔丹建议的那样去JSON,所以我提出了这个解决方案。我只是将html_entity_decode
移到case "text":
块。所以现在我有echo html_entity_decode($child->asXML())."<br/>";
。你觉得这还行吗?
答案 0 :(得分:1)
问题不在于html_entity_decode()
。问题是SimpleXML将<text>
元素的内容视为XML而不是文本。默认情况下,SimpleXML压缩空元素(<a></a>
到<a />
)。解决此问题的一种方法是将SimpleXML对象导入DOM对象,并在saving the output时使用LIBXML_NOEMPTYTAG
选项。此选项的问题在于,任何<br />
元素都将输出为<br></br>
。
更简单的替代方法是使用API中的不同响应格式。我建议使用json
响应格式并使用json_decode()
函数来解析响应。
答案 1 :(得分:1)
这不是奇怪的输出,这是有效的XML。当您有一个空标记时,XML允许您使用在HTML或XHTML中并不总是有效的简短结束语法
<foo></foo>
<foo />
html_entity_decode();
函数转换html实体,例如
> converts to
>
您需要对xml片段进行后处理并将其转换为正确的HTML。最简单的方法是使用DomDocument
API。
$foo = new DomDocument();
$foo->loadHtml('<p> Testing <a href="" /> </p>');
echo $foo->saveHtml();
这将采用XML片段,并将其转换为HTML文档,其中包括修复所有自闭标签。你仍然需要解析<body/>
中的内容,但这比自己修复所有自闭标签容易得多。