douchenzhan3050 2015-06-05 06:58
浏览 23

对通过simplexml_load_file加载的simpleXMLElement进行排序

Before I start my question, I want to point out that I have tried bits and pieces of different codes that was posted here, and I was not too successful.

So I am working on a page that loads in project description data from an external XML file. I have used simplexml_load_file function to load in the xml file.

XML file:

<?xml version='1.0' encoding='UTF-8'?>
<items>
    <item category="Game">
        <year>2015</year>
        <projectName>Some Game</projectName>
        <clientName>Some Company</clientName>
        <imagePath>some_imagefile.png</imagePath>
        <types>
            <type>Work A</type>
            <type>Work B</type>
        </types>
        <languages>
            <language>Language X</language>
            <language>Language Y</language>
            <language>Language Z</language>
        </languages>
        <platforms>
            <platform>Device 1</platform>
        </platforms>
        <visible>false</visible>
    </item>
</items>

The above XML file is loaded in my PHP like:

<?php
    $xml = simplexml_load_file("myXMLfile.xml") or die("Error: cannot create object");
?>

I am able to successfully load the XML data and use the retrieved data exactly how I want, except for the fact that it is not ordered.

So I poked around here and there and found out that I can sort my SimpleXMLElement after I transfer the value over to an Array and use usort().

So this is what I did:

function sortByYearDesc($a, $b) {
    if ($a->year == $b->year) {
        return 0;
    }
    return $a->year > $b->year ? -1 : 1;
}

function sortByProjectNameAsc($a, $b) {
    return strcmp($a->projectName, $b->projectName);
}

$xmlArray = array();
foreach ($xml->item as $iTemp) {
    $xmlArray[] = iTemp;
}

usort($xmlArray, "sortByProjectNameAsc");
usort($xmlArray, "sortByYearDesc");

I used two different sorting functions to sort the projects by projectName (ascending) and also by year (descending). So that I have the project displayed by the release year of the game while titles released in the same year are displayed by ascending order of its title.

Backtracking to what I originally had in my code before I added the sort functions, I have been using the loaded SimpleXMLElement by doing something like this:

<?php
    foreach ($xml->item as items) {
        // get_bool is a function that I made to switch a boolean to a String
        if (get_bool($items->visible)) { 
            // echo stuff
            // by stuff I mean any xml data to display
        }
    }
?>

I assumed that I can simply substitute the SimpleXMLElement to an array:

<?php
    foreach ($xmlArray->item as items) {
        // I changed $xml to $xmlArray
        if (get_bool($items->visible)) { 
            // echo stuff
            // by stuff I mean any xml data to display
        }
    }
?>

And I get a message "Warning: Invalid argument supplied for foreach()".

Any suggestions? What am I missing?

***** added *****

First of all, thanks to splash58 for pointing out missing $ in my code. Other than that, I did find a solution myself like below:

function sortByYearDesc($a, $b) {
    // I noticed that the value was compared in String value, not as an integer
    // so I casted each value to int
    if ((int)$a->year == (int)$b->year) {
        return 0;
    }
    return (int)$a->year > (int)$b->year ? -1 : 1;
}

function sortByProjectNameAsc($a, $b) {
    return strcmp($a->projectName, $b->projectName);
}

$xmlArray = array();
foreach ($xml->item as $iTemp) {
    $xmlArray[] = $iTemp;    // changed "iTemp" to "$iTemp"
}

usort($xmlArray, "sortByProjectNameAsc");
usort($xmlArray, "sortByYearDesc");

I was also missing $ in my echo part of the PHP, which I had in my actual code but not in the code that I posted here:

<?php
    // original post:
    // foreach ($xmlArray->item as items) {
    // xmlArray already is an array of "item" so does not need to go to the "item" node
    // and the obvious change from "items" to "$items"
    foreach ($xmlArray as $items) {
        // I changed $xml to $xmlArray
        if (get_bool($items->visible)) { 
            // echo stuff
            // by stuff I mean any xml data to display
        }
    }
?>
  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥30 win from 窗口最大最小化,控件放大缩小,闪烁问题
    • ¥20 易康econgnition精度验证
    • ¥15 msix packaging tool打包问题
    • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
    • ¥15 python的qt5界面
    • ¥15 无线电能传输系统MATLAB仿真问题
    • ¥50 如何用脚本实现输入法的热键设置
    • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
    • ¥30 深度学习,前后端连接
    • ¥15 孟德尔随机化结果不一致