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

使用PHP SimpleXML判断XML节点文本与子节点的先后顺序

问题原因

SimpleXML 原生设计没有保留混合内容(文本+子元素并存)的节点排列顺序,它会将父节点的直接文本内容和子元素分开存储,因此无法通过 SimpleXMLElement 的原生属性判断二者的先后顺序。

实现方案

你可以配合 PHP 内置的 DOM 扩展实现需求,DOM 扩展完整保留了 XML 节点的实际排列顺序,且可以通过 dom_import_simplexml() 方法和 SimpleXMLElement 无缝转换,无需重写已有逻辑。

完整顺序输出示例代码

<?php
$xml = <<<XML
<?xml version='1.0' standalone='yes'?>
<data>
    <p>
        Hello
        <em>World!</em>
    </p>
    <p>
        <em>Hello </em>
        World!
    </p>
</data>
XML;

$sx = new SimpleXMLElement($xml);
foreach($sx->children() as $p) {
    // 转换SimpleXML节点为DOM节点
    $domP = dom_import_simplexml($p);
    $content = '';
    // 按XML中的实际顺序遍历所有子节点
    foreach ($domP->childNodes as $node) {
        if ($node->nodeType === XML_TEXT_NODE) {
            // 处理文本节点,过滤空白内容
            $text = trim($node->nodeValue);
            $content .= $text ? $text : '';
        } elseif ($node->nodeType === XML_ELEMENT_NODE) {
            // 处理子元素节点
            $content .= trim($node->nodeValue);
        }
    }
    echo $content . PHP_EOL;
}

运行输出:

HelloWorld!
HelloWorld!

先后顺序判断示例代码

如果仅需要判断自身文本和子节点的先后关系,可使用如下逻辑:

foreach($sx->children() as $idx => $p) {
    $domP = dom_import_simplexml($p);
    $firstNodeType = null;
    foreach ($domP->childNodes as $node) {
        // 跳过无意义的空白文本节点
        if ($node->nodeType === XML_TEXT_NODE && trim($node->nodeValue) === '') {
            continue;
        }
        $firstNodeType = $node->nodeType;
        break;
    }
    
    if ($firstNodeType === XML_TEXT_NODE) {
        echo "第{$idx}个p节点:自身文本在子节点之前" . PHP_EOL;
    } elseif ($firstNodeType === XML_ELEMENT_NODE) {
        echo "第{$idx}个p节点:子节点在自身文本之前" . PHP_EOL;
    }
}

运行输出:

第0个p节点:自身文本在子节点之前
第1个p节点:子节点在自身文本之前

内容的提问来源于stack exchange,提问作者T-Regex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 02:36:02