我有一个结构化的xml文件
Run Code Online (Sandbox Code Playgroud)<?xml version="1.0"?> <library> <book id="1003"> <title>Jquery MVC</title> <author>Me</author> <price>500</price> </book> <book id="1001"> <title>Php</title> <author>Me</author> <price>600</price> </book> <book id="1002"> <title>Where to use IFrame</title> <author>Me</author> <price>300</price> </book> </library>
为了根据书籍ID对此xml进行排序,
我编码像这样
$dom = new DOMDocument();
$dom->load('DOM.xml');
$library = $dom->documentElement;
$xpath = new DOMXPath($dom);
$result = $xpath->query('/library/book');
function sort_trees($t1,$t2){
return strcmp($t1['id'], $t2['id']);
}
usort($result, 'sort_trees');
print_r($result);*/
Run Code Online (Sandbox Code Playgroud)
但它给了我一个错误
警告:usort()期望参数1是数组,第24行的/var/www/html/testphp/phpxml/readxml.php中给出的对象
Fra*_*ila 10
您引用的答案是SimpleXML,但您使用的是DOMDocument.
如果您想继续使用DOMDocument,您需要牢记其API.
$dom = new DOMDocument();
$dom->load('DOM.xml');
$xp = new DOMXPath($dom);
$booklist = $xp->query('/library/book');
// Books is a DOMNodeList, not an array.
// This is the reason for your usort() warning.
// Copies DOMNode elements in the DOMNodeList to an array.
$books = iterator_to_array($booklist);
// Second, your sorting function is using the wrong API
// $node['id'] is SimpleXML syntax for attribute access.
// DOMElement uses $node->getAttribute('id');
function sort_by_numeric_id_attr($a, $b)
{
return (int) $a->getAttribute('id') - (int) $b->getAttribute('id');
}
// Now usort()
usort($books, 'sort_by_numeric_id_attr');
// verify:
foreach ($books as $book) {
echo $book->C14N(), "\n";
}
Run Code Online (Sandbox Code Playgroud)
如果需要创建新的输出文档并对节点进行排序,请创建新文档,导入根元素,然后按排序顺序导入书籍节点并添加到文档中.
$newdoc = new DOMDocument('1.0', 'UTF-8');
$libraries = $newdoc->appendChild($newdoc->importNode($dom->documentElement));
foreach ($books as $book) {
$libraries->appendChild($newdoc->importNode($book, true));
}
echo $newdoc->saveXML();
Run Code Online (Sandbox Code Playgroud)
但是,更好的方法是使用XSLT:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- file "sort_by_numeric_id.xsl" -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="xml" />
<xsl:template match="node()|@*">
<xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*">
<xsl:sort select="@id" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
然后使用XSLTProcessor(或xsltproc从命令行):
$xsltdoc = new DOMDocument();
$xsltdoc->load('sort_by_numeric_id.xsl');
$xslt = new XSLTProcessor();
$xslt->importStyleSheet($xsltdoc);
// You can now use $xslt->transformTo*() methods over and over on whatever documents you want
$libraryfiles = array('library1.xml', 'library2.xml');
foreach ($libraryfiles as $lf) {
$doc = new DOMDocument();
$doc->load($lf);
// write the new document
$xslt->transformToUri($doc, 'file://'.preg_replace('/(\.[^.]+)?$/', '-sorted$0', $lf, 1);
unset($doc); // just to save memory
}
Run Code Online (Sandbox Code Playgroud)