如何使用DOM对xml文件进行排序 [英] How to sort a xml file using DOM

查看:75
本文介绍了如何使用DOM对xml文件进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似

<?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进行排序,

In order to sort this xml according to the book id,

在查看 stackoverflow中的此方法

我这样编码

$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);*/

但这给我一个错误

警告:usort()期望参数1为数组,对象在第24行的/var/www/html/testphp/phpxml/readxml.php中给出

Warning: usort() expects parameter 1 to be array, object given in /var/www/html/testphp/phpxml/readxml.php on line 24

推荐答案

您引用的答案是针对SimpleXML,但您使用的是DOMDocument.

The answer you cite is for SimpleXML, but you are using DOMDocument.

如果要继续使用DOMDocument,则需要牢记其API.

If you want to continue to use DOMDocument you need to keep its API in mind.

$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";
}

如果您需要创建一个带有排序节点的新输出文档,请创建一个新文档,导入根元素,然后以排序顺序导入书籍节点并添加到文档中.

If you need to create a new output document with the nodes sorted, create a new document, import the root element, then import the book nodes in sorted order and add to the document.

$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();

但是,更好的方法是使用XSLT:

However, a much better approach is to use 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>

然后使用XSLTProcessor(或从命令行使用xsltproc):

Then use XSLTProcessor (or xsltproc from the command line):

$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
}

这篇关于如何使用DOM对xml文件进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆