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

如何使用PHP的SimpleXML对XML属性进行排序?

问题描述

需要对XML中subscriber节点的tariffSpaceName属性进行排序,让同名条目归为一组。尝试用sort()函数时系统提示需传入字符串,当前PHP代码和XML片段如下:

原PHP代码

<?php
if (file_exists('2023-04-23-3622216414-5_13324_10_00_100005-s.xml')) {
    $xml = simplexml_load_file('2023-04-23-3622216414-5_13324_10_00_100005-s.xml');

?>
<html>
    <table>
        <tr>
            <th>tariffSpaceName</th>
            <th>serviceNumber</th>
            <th>coreProductNumber</th>
        </tr>


<?php
$count = count($xml->subscribers->subscriber);
for($aa=0; $aa<$count; $aa++) {

  foreach($xml->subscribers->subscriber[$aa]->attributes() as $key => $val) {
    if($key == "tariffSpaceName"){
sort($key);
      echo "<tr><td>[1]" . $val . "</td>";
    }

    if($key == "serviceNumber"){
      echo "<td>[2]" . $val . "</td>";
    }

    if($key == "summaryPriceWithTax"){
        echo "<td>[3]" . $val . "</td></tr>";
    }
  }

}
 echo "------<br>";
}else {
    exit('Failed to open test.xml.');
}

?>
</table>
</html>

XML片段(单个subscriber节点)

<subscribers>
        <subscriber accountType="CUST" ownerRefNum="3622216414" ownerCustCode="" phoneNumber="601177068" customerAccountNumber="3622216414" tariffSpaceNumber="5900349478" tariffSpaceName="Böhmová Zdeňka" coreProductNumber="601177068" serviceNumber="601177068" parentServiceNumber="3622216414" serviceStatus="A" summaryPrice="8" summaryPriceTax="1.68" summaryPriceWithTax="9.68" mainTariff="Profil 2" serviceCategory="mobileVoice" noOfEdr="26">
</subscribers>
解决方案

你之前的错误在于直接对属性名字符串$key调用sort()——sort()是用来排序数组的,而且正确逻辑应该是先收集所有subscriber节点,再按tariffSpaceName分组排序。

修正后的代码步骤:

  1. 遍历所有subscriber节点,提取关键属性存入数组
  2. 使用usort()结合多字节字符串比较函数,对数组按tariffSpaceName排序
  3. 遍历排序后的数组生成表格

修正后的完整代码:

<?php
$xmlPath = '2023-04-23-3622216414-5_13324_10_00_100005-s.xml';
if (!file_exists($xmlPath)) {
    exit('Failed to open XML file.');
}

$xml = simplexml_load_file($xmlPath);
$subscribers = [];

// 收集所有subscriber的关键属性到数组
foreach ($xml->subscribers->subscriber as $subscriber) {
    $attrs = $subscriber->attributes();
    $subscribers[] = [
        'tariffSpaceName' => (string)$attrs->tariffSpaceName,
        'serviceNumber' => (string)$attrs->serviceNumber,
        'coreProductNumber' => (string)$attrs->coreProductNumber,
        'summaryPriceWithTax' => (string)$attrs->summaryPriceWithTax
    ];
}

// 按tariffSpaceName排序,支持带重音的特殊字符
usort($subscribers, function($a, $b) {
    return mb_strcoll($a['tariffSpaceName'], $b['tariffSpaceName']);
});
?>
<html>
    <table border="1">
        <tr>
            <th>tariffSpaceName</th>
            <th>serviceNumber</th>
            <th>coreProductNumber</th>
            <th>summaryPriceWithTax</th>
        </tr>
        <?php foreach ($subscribers as $sub) : ?>
        <tr>
            <td><?php echo htmlspecialchars($sub['tariffSpaceName']); ?></td>
            <td><?php echo htmlspecialchars($sub['serviceNumber']); ?></td>
            <td><?php echo htmlspecialchars($sub['coreProductNumber']); ?></td>
            <td><?php echo htmlspecialchars($sub['summaryPriceWithTax']); ?></td>
        </tr>
        <?php endforeach; ?>
    </table>
</html>

关键说明

  • 原代码中sort($key)完全无效:$key是属性名字符串,sort()要求传入数组,且这步逻辑和节点排序无关。
  • 收集属性时必须用(string)转换SimpleXML对象,避免后续排序出现类型错误。
  • 使用mb_strcoll而非普通字符串比较,是为了正确处理带重音的字符(比如示例中的Böhmová Zdeňka),保证排序符合语言规则。
  • 加入htmlspecialchars()是为了防止XML中的特殊字符破坏HTML结构,提升页面安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 18:40:43