【问题标题】:How to extract and Sort a Multidimensional Array data with PHP from a XML file (using simpleXML)如何使用 PHP 从 XML 文件中提取和排序多维数组数据(使用 simpleXML)
【发布时间】:2020-02-11 15:31:34
【问题描述】:

希望你能帮我解决我的问题...

我有这个 XML 文件,我正在使用函数 simplexml_load_file() 获取信息:

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <Xiami>
    <ArtistID>179</ArtistID>
    <ArtistName>Band 1</ArtistName>
    <XiamiID>9dl4gN1c745</XiamiID>
    <Streaming>246</Streaming>
    <Fans>84</Fans>
    <TotalComments>1992</TotalComments>
      <AllSongs>
        <Songs>
          <SongID>8ILroS998dc</SongID>
          <SongName>Song 1</SongName>
          <SongComments>9223</SongComments>
        </Songs>
        <Songs>
          <SongID>8ILLD61a351</SongID>
          <SongName>Song 2</SongName>
          <SongComments>7221</SongComments>
        </Songs>
        <Songs>
          <SongID>mTnf0L5d6b9</SongID>
          <SongName>Song 3</SongName>
          <SongComments>21212</SongComments>
        </Songs>
        <Songs>
          <SongID>xOd2YIc7f69</SongID>
          <SongName>Song 4</SongName>
          <SongComments>422</SongComments>
        </Songs>
        <Songs>
          <SongID>mTmg866314c</SongID>
          <SongName>Song 5</SongName>
          <SongComments>81211</SongComments>
        </Songs>
    </AllSongs>
  </Xiami>
</rss>

这是我用来获取数据的代码:

<?php
    foreach($xml->children() as $Artist) {
        $ArtistName     = $Artist->ArtistName;
        $Streaming      = $Artist->Streaming;
        $Fans           = $Artist->Fans;
        $SongsArrays    = $Artist->AllSongs;
        $SongsCount     = $Artist->AllSongs->Song->count();
    }
?>

如果我打印 print_r($SongsArrays),我会得到以下数组:

SimpleXMLElement Object
(
    [Song] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [SongID] => 8ILroS998dc
                    [SongName] => Song 1
                    [SongComments] => 9223
                )
            [1] => SimpleXMLElement Object
                (
                    [SongID] => 8ILLD61a351
                    [SongName] => Song 2
                    [SongComments] => 7221
                )
            [2] => SimpleXMLElement Object
                (
                    [SongID] => mTnf0L5d6b9
                    [SongName] => Song 3
                    [SongComments] => 21212
                )
            [3] => SimpleXMLElement Object
                (
                    [SongID] => xOd2YIc7f69
                    [SongName] => Song 4
                    [SongComments] => 422
                )
            [4] => SimpleXMLElement Object
                (
                    [SongID] => mTmg866314c
                    [SongName] => Song 5
                    [SongComments] => 81211
                )
        )
)

如果我打印整个数组,我会得到这个:

SimpleXMLElement Object
(
    [ArtistID] => 179
    [ArtistName] => Band 1
    [XiamiID] => 9dl4gN1c745
    [Streaming] => 246
    [Fans] => 84
    [AllSongs] => SimpleXMLElement Object
        (
            [Song] => Array
                (
                    [0] => SimpleXMLElement Object
                        (
                            [SongID] => 8ILroS998dc
                            [SongName] => Song 1
                            [SongComments] => 9223
                        )
                    [1] => SimpleXMLElement Object
                        (
                            [SongID] => 8ILLD61a351
                            [SongName] => Song 2
                            [SongComments] => 7221
                        )
                    [2] => SimpleXMLElement Object
                        (
                            [SongID] => mTnf0L5d6b9
                            [SongName] => Song 3
                            [SongComments] => 21212
                        )
                    [3] => SimpleXMLElement Object
                        (
                            [SongID] => xOd2YIc7f69
                            [SongName] => Song 4
                            [SongComments] => 422
                        )
                    [4] => SimpleXMLElement Object
                        (
                            [SongID] => mTmg866314c
                            [SongName] => Song 5
                            [SongComments] => 81211
                        )
                )
        )
)

问题是:

  1. 如何提取具有更多 cmets 的前 3 首歌曲(获取 cmets、名称和 ID)
  2. 如何将所有 cmets 相加?...

我已经尝试了谷歌和其他论坛推荐的几乎所有东西,但是如果不编写大量代码(分离每个数组并创建大量循环)就找不到如何获取这些数据......有没有更快更简单的方法这样做?

【问题讨论】:

    标签: php xml simplexml


    【解决方案1】:

    您可以使用此功能为艺术家提取最流行的歌曲。它使用xpathAllSongs 中获取Songs,然后usortSongComments 降序对该列表进行排序,最后使用array_slice 仅返回3 首最受欢迎的歌曲:

    function popular_songs($Artist) {
        $Songs = $Artist->xpath('//Songs');
        usort($Songs, function ($a, $b) { return $b->SongComments - $a->SongComments; });
        return array_slice($Songs, 0, 3);
    }
    

    在您的循环中,您可以将其称为:

    $PopularSongs   = popular_songs($Artist);
    

    如果您然后print_r($PopularSongs),您将获得(用于您的示例数据)

    Array
    (
        [0] => SimpleXMLElement Object
            (
                [SongID] => mTmg866314c
                [SongName] => Song 5
                [SongComments] => 81211
            )
        [1] => SimpleXMLElement Object
            (
                [SongID] => mTnf0L5d6b9
                [SongName] => Song 3
                [SongComments] => 21212
            )
        [2] => SimpleXMLElement Object
            (
                [SongID] => 8ILroS998dc
                [SongName] => Song 1
                [SongComments] => 9223
            )
    )
    

    要获得每位艺术家的总 cmets,您可以使用以下代码,它会查找所有 SongComment 元素,将它们转换为整数并将它们相加:

    $TotalComments  = array_reduce($Artist->xpath('//SongComments'), function ($c, $v) { return $c + $v; }, 0);
    

    对于您的示例数据,这给出了 119289。

    Demo on 3v4l.org

    【讨论】:

    • 当我想获得前 3 名 cmets 时非常完美!!!非常感谢!!
    • @MarcoRios 不用担心 - 我很高兴能提供帮助。如果这确实解决了您的问题,请考虑将答案标记为已接受(上/下投票箭头下的复选标记)。见stackoverflow.com/help/someone-answers
    • 我仍在尝试获取所有 cmets 的总和,而无需执行每个数组 ($Artist->Songs[0]->SongComments+$Artist->Songs[1]-> SongComments....等...)...但是,是的,有点解决了...谢谢!!!
    • @MarcoRios 对不起!我错过了问题的那一部分。我已经为答案添加了一个解决方案。
    • @MarcoRios 我想了更多,想出了一种更有效的方法来获取总 cmets。查看我的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多