2012-10-06 48 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