使用 PHP 按一个节点的字母顺序对 XML 行进行排序
Sort XML rows alphabetically by one node, using PHP
这是我的例子 XML:
<ROW>
<DEPT_CODE>11111</DEPT_CODE>
<DEPARTMENT>Program Name</DEPARTMENT>
<BLDG_CODE>BLCG</BLDG_CODE>
<ADDR_STREET1>123 Main Street</ADDR_STREET1>
<ADDR_STREET2>Suite 456</ADDR_STREET2>
<ADDR_STREET3>Lower Level</ADDR_STREET3>
<ADDR_CITY>New York</ADDR_CITY>
<ADDR_STATE>NY</ADDR_STATE>
<ADDR_ZIP>101010</ADDR_ZIP>
<PHONE>212-555-1234</PHONE>
<FAX>212-555-5678</FAX>
<EMAIL>email@company.com</EMAIL>
<URL>http://www.company.com</URL>
</ROW>
这是我的 PHP:
<?php
$xml = simplexml_load_file('department.xml');
foreach($xml->children() as $depts) {
echo $depts->DEPARTMENT . "<br />";
}
?>
它正确地输出部门列表,按照它们在 XML 中出现的顺序,但我希望它按 DEPARTMENT 节点对 alpha 进行排序。
如果所有部门都是唯一的,请执行:
<?php
$xml = simplexml_load_file('department.xml');
foreach($xml->children() as $depts) {
$collect[(string)$depts->DEPARTMENT]=$depts;
}
ksort($collect);
foreach($collect as $depts) {
echo $depts->DEPARTMENT . "<br />";
}
?>
我认为该示例与您的 XML 不匹配。它只包含一个 ROW,因此对其进行排序是没有意义的。假设您有类似的东西:
<records>
<ROW>
<DEPT_CODE>11111</DEPT_CODE>
<DEPARTMENT>Program Name DEF</DEPARTMENT>
</ROW>
<ROW>
<DEPT_CODE>12222</DEPT_CODE>
<DEPARTMENT>Program Name ABC</DEPARTMENT>
</ROW>
</records>
您需要先获取所有 ROW
个元素。 SimpleXML 增加了很多接口和语法魔法。但是 SimpleXMLElement::xpath()
可以 return 一个对象数组。获得数组后,您可以使用 uasort()
通过比较函数对其进行排序。
$records = simplexml_load_string($xml);
$list = $records->xpath('/*/ROW');
uasort(
$list,
function($one, $two) {
return strcasecmp($one->DEPARTMENT, $two->DEPARTMENT);
}
);
var_dump($list);
输出:
array(2) {
[1]=>
object(SimpleXMLElement)#3 (2) {
["DEPT_CODE"]=>
string(5) "12222"
["DEPARTMENT"]=>
string(16) "Program Name ABC"
}
[0]=>
object(SimpleXMLElement)#2 (2) {
["DEPT_CODE"]=>
string(5) "11111"
["DEPARTMENT"]=>
string(16) "Program Name DEF"
}
}
btw 在 DOM 中它看起来像这样:
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$list = iterator_to_array($xpath->evaluate('/*/ROW'));
uasort(
$list,
function($one, $two) use ($xpath) {
return strcasecmp(
$xpath->evaluate('string(DEPARTMENT)', $one),
$xpath->evaluate('string(DEPARTMENT)', $two)
);
}
);
var_dump($list);
以上所有答案似乎都显示了我最终得到的结果的一部分,但我添加了最终结果以防对其他人有帮助:
$xml = simplexml_load_file('data.xml');
foreach($xml->children() as $departments) {
(string)$collect[(string)$departments->DEPT_NAME]=$departments;
}
usort ($collect, function($a, $b) {
return strcmp($a->DEPT_NAME, $b->DEPT_NAME);
});
echo "<ul>";
foreach($collect as $departments) {
if ($departments->DEPT_NAME != "") {
echo "<li>" . $departments->DEPT_NAME . "</li>";
}
}
echo "</ul>";
这是我的例子 XML:
<ROW>
<DEPT_CODE>11111</DEPT_CODE>
<DEPARTMENT>Program Name</DEPARTMENT>
<BLDG_CODE>BLCG</BLDG_CODE>
<ADDR_STREET1>123 Main Street</ADDR_STREET1>
<ADDR_STREET2>Suite 456</ADDR_STREET2>
<ADDR_STREET3>Lower Level</ADDR_STREET3>
<ADDR_CITY>New York</ADDR_CITY>
<ADDR_STATE>NY</ADDR_STATE>
<ADDR_ZIP>101010</ADDR_ZIP>
<PHONE>212-555-1234</PHONE>
<FAX>212-555-5678</FAX>
<EMAIL>email@company.com</EMAIL>
<URL>http://www.company.com</URL>
</ROW>
这是我的 PHP:
<?php
$xml = simplexml_load_file('department.xml');
foreach($xml->children() as $depts) {
echo $depts->DEPARTMENT . "<br />";
}
?>
它正确地输出部门列表,按照它们在 XML 中出现的顺序,但我希望它按 DEPARTMENT 节点对 alpha 进行排序。
如果所有部门都是唯一的,请执行:
<?php
$xml = simplexml_load_file('department.xml');
foreach($xml->children() as $depts) {
$collect[(string)$depts->DEPARTMENT]=$depts;
}
ksort($collect);
foreach($collect as $depts) {
echo $depts->DEPARTMENT . "<br />";
}
?>
我认为该示例与您的 XML 不匹配。它只包含一个 ROW,因此对其进行排序是没有意义的。假设您有类似的东西:
<records>
<ROW>
<DEPT_CODE>11111</DEPT_CODE>
<DEPARTMENT>Program Name DEF</DEPARTMENT>
</ROW>
<ROW>
<DEPT_CODE>12222</DEPT_CODE>
<DEPARTMENT>Program Name ABC</DEPARTMENT>
</ROW>
</records>
您需要先获取所有 ROW
个元素。 SimpleXML 增加了很多接口和语法魔法。但是 SimpleXMLElement::xpath()
可以 return 一个对象数组。获得数组后,您可以使用 uasort()
通过比较函数对其进行排序。
$records = simplexml_load_string($xml);
$list = $records->xpath('/*/ROW');
uasort(
$list,
function($one, $two) {
return strcasecmp($one->DEPARTMENT, $two->DEPARTMENT);
}
);
var_dump($list);
输出:
array(2) {
[1]=>
object(SimpleXMLElement)#3 (2) {
["DEPT_CODE"]=>
string(5) "12222"
["DEPARTMENT"]=>
string(16) "Program Name ABC"
}
[0]=>
object(SimpleXMLElement)#2 (2) {
["DEPT_CODE"]=>
string(5) "11111"
["DEPARTMENT"]=>
string(16) "Program Name DEF"
}
}
btw 在 DOM 中它看起来像这样:
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$list = iterator_to_array($xpath->evaluate('/*/ROW'));
uasort(
$list,
function($one, $two) use ($xpath) {
return strcasecmp(
$xpath->evaluate('string(DEPARTMENT)', $one),
$xpath->evaluate('string(DEPARTMENT)', $two)
);
}
);
var_dump($list);
以上所有答案似乎都显示了我最终得到的结果的一部分,但我添加了最终结果以防对其他人有帮助:
$xml = simplexml_load_file('data.xml');
foreach($xml->children() as $departments) {
(string)$collect[(string)$departments->DEPT_NAME]=$departments;
}
usort ($collect, function($a, $b) {
return strcmp($a->DEPT_NAME, $b->DEPT_NAME);
});
echo "<ul>";
foreach($collect as $departments) {
if ($departments->DEPT_NAME != "") {
echo "<li>" . $departments->DEPT_NAME . "</li>";
}
}
echo "</ul>";