PHP 排序和更新节点 [英] PHP sort and update nodes

查看:20
本文介绍了PHP 排序和更新节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一整天都在与这个斗争:(

I've been battling with this all day :(

虽然我找到了类似问题的答案,但它们不会更新现有的 XML,而是会创建一个新的 XML.

Although I found answers for similar questions they don't update an existing XML, they create a new XML.

非常感谢任何帮助.

这是我正在加载并尝试仅对图像进行排序的 XML->图像节点:

This is the XML I'm loading and trying to sort just the images->image nodes:

<?xml version="1.0"?>
<stuff>
    <other_nodes>
    </other_nodes>
    <images>
        <image><sorted_number><![CDATA[1]]></sorted_number></image>
        <image><sorted_number><![CDATA[3]]></sorted_number></image>
        <image><sorted_number><![CDATA[2]]></sorted_number></image>
    </images>
</stuff>

//load the xml into a var
$theXML = //load the xml from the database

$imageNode = $theXML->images;

//sort the images into sorted order
$d = $imageNode;

// turn into array
$e = array();
foreach ($d->image as $image) {
        $e[] = $image;
}
// sort the array
usort($e, function($a, $b) {
        return $a->sorted_number - $b->sorted_number;
});



//now update the xml in the correct order

foreach ($e as $node) { 

//???unsure how to update the images node in my XML

}

推荐答案

SimpleXML 对于您的任务来说太简单.没有简单的方法来重新排序节点.基本上,在你的排序程序之后,你必须重建 节点,但是你有 CDATA 里面,而 SimpleXML 不能直接添加 CDATA 值.

SimpleXML is too simple for your task. There is no easy way to reorder nodes. Basically, after your sorting routine, you have to reconstruct <image> nodes, but you have CDATA inside, and SimpleXML can't directly add CDATA value.

如果你想通过这种方式尝试,这里你可以找到一个很酷的SimpleXML类添加 CDATA 属性的扩展,但此解决方案也使用 DOMDocument.

If you want try by this way, here you can find a cool SimpleXML class extension that add CDATA property, but also this solution use DOMDocument.

基本上,恕我直言,因为每个解决方案都需要 DOM,最好的方法是直接使用 DOMDocument 并且——最终——(重新)加载 XML 与 SimpleXML 转换后:

Basically, IMHO, since every solution require DOM, the best way is to use directly DOMDocument and — eventually — (re)load XML with SimpleXML after transformation:

$dom = new DOMDocument();
$dom->loadXML( $xml, LIBXML_NOBLANKS );
$dom->formatOutput = True;

$images = $dom->getElementsByTagName( 'image' );

/* This is the same as your array conversion: */
$sorted = iterator_to_array( $images );

/* This is your sorting routine adapted to DOMDocument: */
usort( $sorted, function( $a, $b )
{
    return
    $a->getElementsByTagName('sorted_number')->item(0)->nodeValue
    -
    $b->getElementsByTagName('sorted_number')->item(0)->nodeValue;
});

/* This is the core loop to "replace" old nodes: */
foreach( $sorted as $node ) $images->item(0)->parentNode->appendChild( $node );

echo $dom->saveXML();

eval.in 演示

主程序将已排序的节点作为子节点添加到现有的 节点.请注意,不需要预先删除旧的孩子:因为我们引用了同一个对象,实际上通过附加一个节点,我们将它从之前的位置删除了.

The main routine add sorted nodes as child to existing <images> node. Please note that there is no need to pre-remove old childs: since we refer to same object, by appending a node in fact we remove it from its previous position.

如果你想获得一个 SimpleXML 对象,你可以在上面的代码末尾添加这一行:

If you want obtain a SimpleXML object, at the end of above code you can append this line:

$xml = simplexml_load_string( $dom->saveXML() );

这篇关于PHP 排序和更新节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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