2012-10-06 47 views
1

我正在排序&从XML文件分组发布数据。我目前使用的方法大多数部分工作正常,尽管我觉得有一种更有效的方式来完成我正在尝试完成的任务。排序和分组SimpleXML数据

这里的目标节点是什么样子的样本:

<comic> 
     <id>117</id> 
     <mainsection> 
     <series> 
      <displayname>My Amazing Adventure</displayname> 
      <sortname>My Amazing Adventure</sortname> 
     </series> 
     </mainsection> 
     <issuenr>2</issuenr> 
     <seriefirstletter> 
     <displayname>M</displayname> 
     <sortname>M</sortname> 
     </seriefirstletter> 
    </comic> 

这里有我充分利用了当前的步骤。

  • 载入用SimpleXML
  • 指定目标节点的XML文件,并用iterator_to_array将其转换为一个数组
  • 使用其比较usort函数(的strcmp)的SERIESNAME属性,排序所有系列的按字母顺序排列。
  • 我使用每个页面的查询字符串来指定字母表的每个字母,并使用将查询字符串字母与系列字母值进行比较的IF语句。所以只返回适用的节点。
  • 然后我开始我的foreach语句。将我想要的数据回复到LI项目中。
  • 最后,我使用jQuery来查看每个LI项目的ID并对其进行可视化分组。我已经创建了一个PHP变量,它使用了serialname,删除了空格,用于ID。它在组上方插入带有正确系列名称的H4标题,并在组下方插入一个分隔DIV。

虽然按字母排序工作正常。我也想让同一系列内的问题按数字排序。 这目前没有工作。现在,数字排序顺序看起来像这样:1,10,12,2,3.

我想弄清楚数值排序问题。我也觉得我目前在jQuery中做的分组可以在PHP中完成,而我正在经历循环。任何意见,以更好/更有效的方式来处理这些数据,将不胜感激。

+1

对于排序 - 如以前的评论中所建议的 - 使用自然顺序。请参阅http://stackoverflow.com/a/8989994/367456 – hakre

+0

@hakre - 谢谢。我确实看到了。但是,根据我所知,natsort使用它在数组项中找到的第一个文本对其进行排序。从上面的示例节点可以看到,系列名称不是节点中的第一个文本。此外,我不知道如何让它抓住问题编号。 – Batfan

回答

1

比方说,你已经得到了所有已经有3210个元素作为迭代器。首先,它转换成一个数组,所以我们可以使用数组功能:

$comics = iterator_to_array($comics, 0); 

那么你一定要基于一定的价值这个数组排序,在<issuenr>孩子,这里的价值。这可以用usort完成和一个回调函数的帮助:

$success = usort($comics, function($a, $b) { 
    return strnatcmp($a->issuenr, $b->issuenr); 
}); 

回调函数只挑选你想与对方比较具体的值,并将它传递给strnatcmp这是我评论的自然顺序比较以上。


下面的代码示例演示了如何列出符合特定搜索字母,natsort版和独特(没有重复的名字,分组)的所有系列。

搜索和分组都与一个xpath查询完成:

$searchval = 'T'; 

$file = 'compress.zlib://comiclist10-12.xml.gz'; 

$xml = simplexml_load_file($file); 

$series = $xml->xpath(
    "/*/comiclist/comic[./seriefirstletter/displayname = '$searchval'] 
     /mainsection/series/sortname[ 
      not(. = ../../../following-sibling::comic/mainsection/series/sortname) 
     ]" 
); 

natsort($series); 

foreach($series as $serie) 
{ 
    echo $serie, "\n"; 
} 

这一操作将输出排序列表:

Tale of the Batman: Gotham by Gaslight, A 
Tales of Suspense: Captain America & Iron Man #1 Commemorative Edition 
Tales to Astonish, Vol. 1 
Teenage Mutant Ninja Turtles 
Teenage Mutant Ninja Turtles Micro Series 
Teenage Mutant Ninja Turtles Ongoing 
Terminator/Robocop: Kill Human 
Thanos 
Thing, Vol. 1 
Thor, Vol. 2 
Thor, Vol. 3 
Thor: Blood Oath 
Thor: For Asgard 
Thor: Man of War 
Thor: Son of Asgard 
Thor Annual 
Thor Corps 
Thundercats 
Thundercats (DC Comics - Wildstorm) 
Thundercats: Enemy's Pride 
Tomb of Dracula, Vol. 4, The 
Torch, The 
Toxin 
Transformers: Armada 
Transformers: Generation One 
Transformers: Infiltration 
Truth: Red, White & Black 

在接下来的步骤要列出所有漫画中该系列,这将是一个内部的foreach:

foreach ($series as $serie) { 
    echo $serie, "\n"; 

    $string = xpath_string($serie); 

    $comics = $serie->xpath("../../../../comic[./mainsection/series/sortname = $string]"); 

    foreach ($comics as $i => $comic) { 
     printf(" %d. id: %s\n", $i+1, $comic->id); 
    } 
} 

哪会然后取出每个系列的漫画,输出:

Tale of the Batman: Gotham by Gaslight, A 
1. id: 8832 
Tales of Suspense: Captain America & Iron Man #1 Commemorative Edition 
1. id: 3591 
Tales to Astonish, Vol. 1 
1. id: 3589 
Teenage Mutant Ninja Turtles 
1. id: 117 
Teenage Mutant Ninja Turtles Micro Series 
1. id: 13789 
Teenage Mutant Ninja Turtles Ongoing 
1. id: 13780 
2. id: 13782 
3. id: 13787 
Terminator/Robocop: Kill Human 
1. id: 13775 
Thanos 
1. id: 3597 
Thing, Vol. 1 
1. id: 3746 
Thor, Vol. 2 
1. id: 5873 
Thor, Vol. 3 
1. id: 1035 
2. id: 1635 
3. id: 2318 
4. id: 2430 
5. id: 2463 
6. id: 3333 
7. id: 3616 
8. id: 11731 
9. id: 11733 
Thor: Blood Oath 
1. id: 3635 
2. id: 3636 
Thor: For Asgard 
1. id: 11545 
2. id: 11546 
Thor: Man of War 
1. id: 3644 
Thor: Son of Asgard 
1. id: 538 
2. id: 3645 
Thor Annual 
1. id: 5868 
Thor Corps 
1. id: 3640 
Thundercats 
1. id: 209 
Thundercats (DC Comics - Wildstorm) 
1. id: 3654 
Thundercats: Enemy's Pride 
1. id: 3649 
Tomb of Dracula, Vol. 4, The 
1. id: 3719 
Torch, The 
1. id: 2328 
2. id: 2330 
3. id: 2461 
Toxin 
1. id: 3720 
Transformers: Armada 
1. id: 3737 
Transformers: Generation One 
1. id: 557 
Transformers: Infiltration 
1. id: 3729 
2. id: 3731 
Truth: Red, White & Black 
1. id: 3750 
2. id: 3751 

xpath_string function can be found in another answer of mine的代码。

+0

我想我明白,但是,我如何将这个应用到每个系列。从我看到的情况来看,我需要获取某个系列中的所有节点,然后将这些节点放入数组中,然后使用这种排序方法对问题进行数字排序。对? – Batfan

+0

是的,就是这样。排序将在数组中,所以将排序最初由'$ comics'迭代器提供的所有内容。但是,该代码是PHP 5.3,而不是5.2。您需要使用名称(而不是匿名)创建自己的函数,然后使用函数名作为带usort的字符串,请参阅http://php.net/usort以获得一般示例。 – hakre

+0

对于抓取系列组,你会有什么建议?因为我猜我不得不在循环中引用当前节点的系列。我的第一个直觉是另一个foreach,但是,我的印象是我不能在foreach循环中做一个foreach。 – Batfan

1

您可以使用

$key = "id" ; 
$iterator = new SimpleXMLIterator($xml); 
$array = json_decode(json_encode($iterator), TRUE); 
__xsort($array['comic'],"id") ; 
var_dump($array['comic']); 

输出

array 
    0 => 
    array 
     'id' => string '1' (length=1) 
     'mainsection' => 
     array 
      'series' => 
      array 
       ... 
    1 => 
    array 
     'id' => string '2' (length=1) 
     'mainsection' => 
     array 
      'series' => 
      array 
       ... 
    2 => 
    array 
     'id' => string '3' (length=1) 
     'mainsection' => 
     array 
      'series' => 
      array 
       ... 
    3 => 
    array 
     'id' => string '10' (length=2) 
     'mainsection' => 
     array 
      'series' => 
      array 
       ... 
    4 => 
    array 
     'id' => string '12' (length=2) 
     'mainsection' => 
     array 
      'series' => 
      array 
       ... 

XML使用

$xml = "<comics> 
<comic> 
     <id>1</id> 
     <mainsection> 
     <series> 
      <displayname>My Amazing Adventure - 1</displayname> 
      <sortname>My Amazing Adventure</sortname> 
     </series> 
     </mainsection> 
    </comic> 

<comic> 
     <id>10</id> 
     <mainsection> 
     <series> 
      <displayname>My Amazing Adventure - 10</displayname> 
      <sortname>My Amazing Adventure</sortname> 
     </series> 
     </mainsection> 
    </comic> 

<comic> 
     <id>12</id> 
     <mainsection> 
     <series> 
      <displayname>My Amazing Adventure 12</displayname> 
      <sortname>My Amazing Adventure</sortname> 
     </series> 
     </mainsection> 
    </comic> 

<comic> 
     <id>2</id> 
     <mainsection> 
     <series> 
      <displayname>My Amazing Adventure 2</displayname> 
      <sortname>My Amazing Adventure</sortname> 
     </series> 
     </mainsection> 
    </comic> 


<comic> 
     <id>3</id> 
     <mainsection> 
     <series> 
      <displayname>My Amazing Adventure 3</displayname> 
      <sortname>My Amazing Adventure</sortname> 
     </series> 
     </mainsection> 
    </comic> 

</comics>" ; 

__xsort Function Used

+0

在__xsort函数的第二行发生“意外的T_FUNCTION”错误。 – Batfan

+0

看到__xsort功能在这里http://stackoverflow.com/a/12759674/1226894 ..不想重复的代码 – Baba

+0

是的,我看到了链接,并复制了确切的。仍然出现错误。 – Batfan