You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PHP XPath简化TinyMCE Checklist转TCPDF兼容格式的代码?

简化TinyMCE复选列表转TCPDF兼容格式的PHP XPath代码

我通过TinyMCE编辑器创建包含{NAME}、{SURNAME}等占位符的模板(比如文本、发票),在Web应用的其他页面用PHP替换占位符后,再用TCPDF类生成最终PDF。现在需要处理TinyMCE checklist插件生成的内容,把编辑器里的复选列表转换为TCPDF可识别的[ ]/[X]格式。我知道可以用PHP XPath实现,但之前没接触过,不清楚如何定位这类复杂文本片段。

TinyMCE生成的复选框HTML示例

<ul class="tox-checklist">
 <li> checkbox 1</li>
 <li class="tox-checklist--checked"> checkbox 2</li>
</ul>

目标TCPDF兼容格式

<p>[ ] checkbox 1</p>
 <p>[X] checkbox 2</p>

已知插件用.tox-checklist类标记UL列表,.tox-checklist--checked类标记已选中的复选框,模板中可能存在多个这类列表。我已经实现了功能,但代码过于繁琐,希望简化现有的PHP XPath代码:

现有繁琐代码

$contenuto = '<ul class="tox-checklist"><li> checkbox 1</li><li class="tox-checklist--checked"> checkbox 2</li></ul>';

$dom = new DOMDocument();
$dom->loadHTML($contenuto);
$xpath = new DOMXpath($dom);
$selector = $xpath->query('//ul[contains(@class,"tox-checklist")]/li[not(contains(@class,"tox-checklist--checked"))]');
foreach ($selector as $node) {

    $testo_checkbox = "[&nbsp;&nbsp;&nbsp;&nbsp;]" . $node->nodeValue;
    
    $parent = new DomDocument;
    $parent_node = $parent->createElement('p', $testo_checkbox);
    $parent->appendChild($parent_node);
    
    $newnode = $dom->importNode($parent->documentElement, true);
    $node->parentNode->replaceChild($newnode, $node);
    
}
$contenuto = $dom->saveHTML();

$dom = new DOMDocument();
$dom->loadHTML($contenuto);
$xpath = new DOMXpath($dom);
$selector = $xpath->query('//ul[contains(@class,"tox-checklist")]/li[contains(@class,"tox-checklist--checked")]');
foreach ($selector as $node) {

    $testo_checkbox = "[ X ]" . $node->nodeValue;
    
    $parent = new DomDocument;
    $parent_node = $parent->createElement('p', $testo_checkbox);
    $parent->appendChild($parent_node);
    
    $newnode = $dom->importNode($parent->documentElement, true);
    $node->parentNode->replaceChild($newnode, $node);
    
}
$contenuto = $dom->saveHTML();

$dom = new DOMDocument();
$dom->loadHTML($contenuto);
$xpath = new DOMXpath($dom);
$selector = $xpath->query('//ul[contains(@class,"tox-checklist")]');
foreach ($selector as $node) {
    $newParent = $node->parentNode;
    foreach ( $node->childNodes as $child ){
        $newParent->insertBefore($child->cloneNode(true), $node);
    }
    $newParent->removeChild($node);
}
$contenuto = $dom->saveHTML();

简化后的代码

可以通过一次加载DOM文档,统一处理所有复选列表项,最后移除原UL容器,大幅减少重复代码:

$contenuto = '<ul class="tox-checklist"><li> checkbox 1</li><li class="tox-checklist--checked"> checkbox 2</li></ul>';

// 加载HTML到DOM,抑制解析错误避免结构问题干扰
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($contenuto);
libxml_clear_errors();
$xpath = new DOMXpath($dom);

// 一次性获取所有目标列表项
$listItems = $xpath->query('//ul[contains(@class, "tox-checklist")]/li');

foreach ($listItems as $li) {
    // 判断是否为选中状态
    $isChecked = str_contains($li->getAttribute('class'), 'tox-checklist--checked');
    // 生成对应复选框前缀
    $checkboxPrefix = $isChecked ? '[X]' : '[ ]';
    // 创建p元素并填充内容
    $p = $dom->createElement('p');
    $p->nodeValue = $checkboxPrefix . $li->nodeValue;
    
    // 替换原li元素
    $li->parentNode->replaceChild($p, $li);
}

// 移除所有空的UL容器
$ulLists = $xpath->query('//ul[contains(@class, "tox-checklist")]');
foreach ($ulLists as $ul) {
    // 将UL的子元素移到父节点下
    while ($ul->firstChild) {
        $ul->parentNode->insertBefore($ul->firstChild, $ul);
    }
    // 删除UL容器
    $ul->parentNode->removeChild($ul);
}

// 输出处理后的HTML
$contenuto = $dom->saveHTML();

简化说明

  1. 单次DOM解析:只初始化一次DOM和XPath实例,避免重复加载HTML
  2. 统一处理列表项:用一个XPath查询获取所有目标li,循环内判断选中状态并生成对应p元素,无需拆分两次处理
  3. 高效清理UL容器:直接移动子元素后删除空UL,省去节点克隆操作
  4. 错误抑制:添加libxml错误处理,避免因HTML结构不完整导致的解析报错

内容的提问来源于stack exchange,提问作者itajackass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:33:26