我正在尝试将存储在旧的MS Access数据库中的RTF文本读取到新的PHP Web应用程序中。清理后的数据将使用CKEditor显示给用户,这对于解析符合标准的HTML代码非常严格。但是,存储在MS Access中的数据通常格式不正确或使用不推荐使用的HTML代码。
以下是我要清理的示例数据:
<div align="right">Previous claim $ 935.00<div align="right"> This claim $1,572.50</div></div>
该数据本来是两行右对齐的文本,但是MS Access使用了已弃用的 align 属性来设置<div>
标签的样式,而不是样式属性,并且在这种情况下它们应该是顺序的时,已经错误地嵌套了它们。
要将示例数据转换为两行均右对齐且CKEditor将按预期读取和显示的文本行(即文本显示为右对齐),我尝试将<div>
标记替换为<p>
标签,然后插入带有正确text-align的内联样式属性以替换不推荐使用的align属性。
我正在使用PHP的DOMXPath清理数据,其代码如下:
$dom = new DOMDocument();
$dom->loadHTML($dataForCleaning, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//div[@align]') as $node) {
$alignment = $node->getAttribute('align');
$newNode = $dom->createElement('p');
$newNode->setAttribute("style", "text-align:".$alignment);
$node->parentNode->insertBefore($newNode, $node);
foreach ($node->childNodes as $child) {
$newNode->appendChild($child);
}
$node->parentNode->removeChild($node);
}
我使用insertBefore
代替appendChild
来尝试保持元素序列相同,但这就是导致此嵌套数据示例中出现问题的原因。
对于非嵌套<div>
标记作为要清除的输入数据,已清理的输出html是正确的。但是,在这个嵌套的<div>
示例中,输出最终为:
<p style="text-align:right">Previous claim $ 935.00</p>
请注意,第二行文本(此声明... )已被删除,因为它位于嵌套<div>
中,作为父级<div>
的子级
我不介意生成的<p>
标签是否仍然嵌套,因为CKEditor最终清理了这些标签,但是我需要确保我不会像当前代码那样丢失数据。
在此先感谢您的帮助和指导。 -马克
答案 0 :(得分:0)
我改变了几件事。首先,我得到的不仅仅是克隆现有节点,而是克隆节点并添加副本(在$newNode->appendChild($child->cloneNode(true));
中),第二件事是在移动封闭的节点时,我认为XPath不再指向此移动的节点。因此,除此以外,我会在复制子节点时检查您是否具有与<div align="right">
节点相同的模式,如果有,我会以新格式创建一个新节点并添加该新节点...
foreach ($xpath->query('//div[@align]') as $node) {
$alignment = $node->getAttribute('align');
$newNode = $dom->createElement('p');
$newNode->setAttribute("style", "text-align:".$alignment);
$node->parentNode->insertBefore($newNode, $node);
foreach ($node->childNodes as $child) {
if ( $child instanceof DOMElement && $child->localName == "div"
&& $child->attributes->getNamedItem("align")->nodeValue == "right" ) {
$subNode = $dom->createElement('p', $child->nodeValue );
$subNode->setAttribute("style", "text-align:".$alignment);
$newNode->appendChild($subNode);
}
else {
$newNode->appendChild($child->cloneNode(true));
}
}
$node->parentNode->removeChild($node);
}
您给出的样本将输出...
<p style="text-align:right">
Previous claim $ 935.00
<p style="text-align:right"> This claim $1,572.50</p>
</p>