0

我有一个充满类似 XML 标记的文件,包括<is:namespace:tag ...>以类似 HTML/XML 的方式排列。这些用于通过 smarty 库的创造性使用来生成和呈现 HTML。我们的模板文件不再有任何聪明之处,我想编写一个渲染引擎,使用 PHP 内置的 XML/DOM 库来解析类似 XML 的内容。遗憾的是,我拥有的类 XML 语言与 PHP 的 XML 解析库不兼容。

所有示例都使用相同的变量:

$template = '<is:namespace:tag attr="value">foo<is:namespace:tag attr="value" /></is:namespace:tag>';

示例(确保打开 PHP 警告!):

$parser = simplexml_load_string($template);
$parser = XMLReader::xml($template);
while($parser->read()) { echo $parser->name; }
$parser = DOMDocument::loadXML($template);
$parser = new SimpleXMLElement($template);

尝试的每种方法都会引发警告 - 请注意,由于违反了 XML 标准,因此QName( is:namespace:tagbit) 是不可解析的,而这些工具旨在遵守该标准。

我也试过:

$parser = DOMDocument::loadHTML($template);

它还抱怨名称空间缺少声明和标记名称无效。

我认识到,如果我的 XML 的内容没有我可以使用的值str_replace或正则表达式来去除:'s,但我强烈希望避免数据修改。

如何使用 PHP 内置的 XML 或 DOM 库来解析这种“改进”的格式?

4

1 回答 1

1

如果 - 除了那个冒号 - XML 的其余部分是“有效的”,那么您很有可能可以简单地使用基于正则表达式的搜索和替换来解决这个问题。

以下行确实将is:namespace部分替换为命名空间前缀ns1

$fixed = preg_replace('((</?)is:namespace(:[a-z]+))', '$1ns1$2', $template);

在将其加载为 XML 文档之前,需要在 XML 文档根(也称为文档)元素中定义前缀:

$fixed = "<root xmlns:ns1='is:namespace'>$fixed</root>";

然后它可以安全地作为 XML 文档加载到任何基于 libxml 的解析器中,例如 SimpleXML:

$parser = simplexml_load_string($fixed);

echo $parser->asXML();

那么输出是:

<?xml version="1.0"?>
<root xmlns:ns1="is:namespace">
  <ns1:tag attr="value">
    foo
    <ns1:tag attr="value"/>
  </ns1:tag>
</root>

另请参阅在线演示。如果您的数据使用 CDATA 并且字符串is:namespace:在其中重复,则存在一种更改,即这将无法安全工作。

于 2013-02-15T14:40:52.080 回答