在我上一个问题的后续步骤中,如果您的 xml 文件中有一个格式错误的字符串,您可以使用 preg_replace_callback() 提取内容以删除中断的元素。
这个函数的重点不是用正则表达式解析 xml(一个坏主意),而是试图找到不解析的 xml 以及它失败的地方,以便我们可以在发送之前标记格式不正确的文章出去。这是在交付前清理内容的一组工具的一部分。我正在对已知的格式错误的公共 RSS url 以及内部 URL 进行测试,以查看它是否适合多种情况。回调将为失败的节点返回一个整数。如果之后通过,我们可以报告文章的索引,然后尝试使用 DOMDocument 尝试更正 html 并重试。如果失败,我们将其报告为关键,否则,我们将解析文章描述和内容返回到数据库,并将其标记为在交付前修改。
然后,您可以获取损坏的元素并通过 DOMDocument 运行它们以更好地格式化它们以返回 XML 文件。
但是,我被困在如何使下面的示例返回 false 之外:
示例 XML:
<item>
<content:encoded><![CDATA[
This is the text with odd characters that are killing
simplexml_load_string() (doesn't recover) and breaking
(although recoverable) DOMDocument
]]></content:encoded>
</item>
如果我使用以下 PHP,我可以提取描述节点并将其转换为:
<description><![CDATA[
This is some description text with the same problem
]]></description>
到
<description>0</description>
PHP:
preg_replace_callback(
'/<description>(.*)<\/description>/', **// add msU modifiers to fix below**
'node_tidy::callback_description',
$xml
);
...
private function callback_description($matches=false) {
if(false !== $matches) {
$this->arrDescriptions[] = $matches[1];
return '<description>'.$this->indexDescriptions++.'</description>';
} else {
return false;
}
}
但是,当我尝试对content:encoded
节点执行相同操作时,它返回 false。这是相关的功能:
private function callback_content_encoded($matches=false) {
if(false !== $matches) {
$this->arrContentEncoded[] = $matches[1];
return '<content:encoded>'.$this->indexContentEncoded++.'</content:encoded>';
} else {
return false;
}
}
使用直接正则表达式来测试它是否是冒号,我使用了这个:
<?php
$string = '<content:encoded>this is some text</content:encoded>';
preg_match('/<content\:encoded>(.*)<\/content\:encoded>/',$string,$matches);
echo '<pre>';
print_r($matches);
echo '</pre>';
?>
但是,无论是否添加\:
. 有人可以为这里的误解指出正确的方向吗?
非常感谢!
更新:这是失败的真实 xml 的示例片段,如@Florent 所示。
更新:这个正则表达式匹配所需的内容:
preg_match('/<content\:encoded>(.*)<\/content\:encoded>/msU',$string,$matches);
m 和 s 和 U 修饰符在这里解释得更好: http ://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
我忽略了考虑这些修饰符。
结果现在由这个正则表达式返回,包括原来的问题,所以现在可以解决这个问题。