2010-03-29 4 views
2

discogs.com (XML) -API의 데이터를 사용하여 페이지를 만들려고합니다. 나는 simpleXML로 파싱 해왔고 꽤 잘 작동하지만 어떻게해야할지 모르겠다. 여기XML 데이터를 PHP로 정렬/그룹화 하시겠습니까?

는 XML의 일부입니다 : 내가 뭘 달성하고자하는에 Discogs는 자료를 제시하는 방법을 similair 뭔가가

<releases> 
    <release id="1468764" status="Accepted" type="Main"> 
    <title>Versions</title> 
    <format>12", EP</format> 
    <label>Not On Label</label> 
    <year>1999</year> 
    </release> 
    <release id="72246" status="Accepted" type="Main"> 
    <title>The M.O.F Blend</title> 
    <format>LP</format> 
    <label>Blenda Records</label> 
    <year>2002</year> 
    </release> 
    <release id="890064" status="Accepted" type="Main"> 
    <title>The M.O.F Blend</title> 
    <format>CD</format> 
    <label>Blenda Records</label> 
    <year>2002</year> 
    </release> 
    <release id="1563561" status="Accepted" type="TrackAppearance"> 
    <title>Ännu En Gång Vol. 3</title> 
    <trackinfo>Backtrack</trackinfo> 
    <format>Cass, Comp, Mix</format> 
    <label>Hemmalaget</label> 
    <year>2001</year> 
    </release> 
</releases> 

: 동일한 릴리스의 개의 다른 버전이 함께 분류되어 http://www.discogs.com/artist/Mics+Of+Fury. (M.O.F Blend in my link 참조) 이것은 다른 릴리스를 특징으로하는 마스터 릴리스가있는 디스 포그에서 수행됩니다. 불행히도이 정보는 API 데이터에 존재하지 않으므로 동일한 <title> 태그를 사용하여 <release> 노드를 그룹화하거나 동일한에 고유 한 <title>이없는 플래그를 추가하여 동일한 작업을 수행하고 싶습니다. 이 일을하는 가장 좋은 방법에 대한 좋은 아이디어가 있습니까?

동일한 유형 속성이있는 <release> - 노드 (하위 버전)를 계산할 수 있는지 알고 싶습니까? 이 예와 같이 "Main"유형의 출시를 계산 하시겠습니까?

아마도 XMLReader 또는 XPath로이 작업을 수행하는 것이 좋습니다.

답변

0

최근에 객체의 HTML 표를 만들고 정렬하는 데 사용하는 클래스를 작성했습니다. 여기에서 연관 배열 정렬에 유용한 일부 정적 메소드가 있습니다. self : :: reference를 제거 했으므로이 메서드를 함수로 사용할 수 있습니다.

사용법 : $array = array_sort($array, 'sort_key_name');

function array_sort(&$array) 
    { 
     if(!$array) return $keys; 
     $keys = func_get_args(); 
     array_shift($keys); 
     array_sort_func($keys); 
     usort($array,array("listview","array_sort_func")); 
     return $array; 
    } 


function array_sort_func($a, $b = NULL) 
    { 
     static $keys; 
     if($b === NULL) return $keys = $a; 

     foreach($keys as $k) 
     { 
      $aval = hod($a, '$a->' . $k); 
      $bval = hod($b, '$b->' . $k); 

      // modify string to compate 
      if(!is_numeric($aval)){$aval = strtolower($aval);} 
      if(!is_numeric($bval)){$bval = strtolower($bval);} 

      if($k[0]=='!') 
      { 
       $k=substr($k,1); 

       if($aval!== $bval) 
       { 
        if(is_numeric($aval) and is_numeric($bval)) 
        { 
         return $aval - $bval; 
        } 
        else 
        { 
         return strcmp($bval, $aval); 
        } 
       } 
      } 
      else if($aval !== $bval) 
      { 
       if(is_numeric($aval) and is_numeric($bval)) 
       { 
        $compare = $aval - $bval; 

        if($compare > 0) 
        { 
         return 1; 
        } 
        elseif($comare < 0) 
        { 
         return -1; 
        } 
       } 
       else 
       { 
        return strcmp($aval, $bval); 
       } 
      } 
     } 

     return 0; 
    } 

function hod(&$base, $path) 
    { 
     $licz = ''; 
     $keys = explode("->", $path); 
     $keys[0] = str_replace('$', '', $keys[0]); 
     $expression = '$ret = '; 
     $expression.= '$'; 

     foreach ($keys as $key) 
     { 
      if (++$licz == 1) 
      { 
       $expression.= 'base->'; 
      } 
      else 
      { 
       $expression.= $key.'->'; 
      } 
     } 

     $expression = substr($expression, 0, -2); 
     $expression.= ';'; 
     eval($expression); 
     return $ret; 
    } 
2

당신은 xsl(t)php's XSLTProcessor를 사용할 수 있습니다. XSLT 2.0
당신이 (하지 않습니다 PHP는 5.3.2의 php.net의는 Win32 빌드에 사용되는 최소 버전)을 지원하지 않습니다 불행하게도

<xsl:for-each-group select="release" group-by="title"> 

libxslt 같은 것을 사용할 수 있습니다.
그러나 Muenchian grouping method을 사용할 수 있습니다.

test.xsl :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="html" version="4.0" encoding="utf-8" indent="yes"/> 

<xsl:key name="release-by-title" match="release" use="title" /> 

<xsl:template match="/"> 
    <html> 
    <head><title>...</title></head> 
    <body> 
     <xsl:apply-templates /> 
    </body> 
    </html> 
</xsl:template> 

<xsl:template match="releases"> 
    <table border="1"> 
    <xsl:for-each select="release[count(. | key('release-by-title', title)[1]) = 1]"> 
     <xsl:sort select="title" /> 
     <tr> 
     <th colspan="3"><xsl:value-of select="title" /></th> 
     </tr> 
     <xsl:for-each select="key('release-by-title', title)"> 
     <xsl:sort select="year" /> 
     <tr> 
      <td><xsl:value-of select="year" /></td> 
      <td><xsl:value-of select="label" /></td> 
      <td><xsl:value-of select="format" /></td> 
     </tr> 
     </xsl:for-each> 
    </xsl:for-each> 
    </table> 
</xsl:template> 

</xsl:stylesheet> 

test.xml의 당신이 제공하는 XML 문서를 포함.
그리고 test.php :

<?php 
$doc = new DOMDocument; 
$doc->load('test.xsl'); 
$stylesheet = new XSLTProcessor; 
$stylesheet->importStyleSheet($doc); 
$doc->load('test.xml'); 

header('Content-type: text/html; charset=utf-8'); 
echo $stylesheet->transformToXML($doc); 

그리고합니다 (< 테이블 > part의 onlye)의 출력은 다음과 같습니다

<table border="1"> 
    <tr><th colspan="3">The M.O.F Blend</th></tr> 
    <tr> 
    <td>2002</td> 
    <td>Blenda Records</td> 
    <td>LP</td> 
    </tr> 
    <tr> 
    <td>2002</td> 
    <td>Blenda Records</td> 
    <td>CD</td> 
    </tr> 
    <tr><th colspan="3">Versions</th></tr> 
    <tr> 
    <td>1999</td> 
    <td>Not On Label</td> 
    <td>12", EP</td> 
    </tr> 
    <tr><th colspan="3">Ännu En Gång Vol. 3</th></tr> 
    <tr> 
    <td>2001</td> 
    <td>Hemmalaget</td> 
    <td>Cass, Comp, Mix</td> 
    </tr> 
</table> 

지금, 그는 explaination의 많은 아니에요. 하지만 어쩌면 검색 할 내용에 대한 힌트를 줄 수 있습니다.

0

xslt 2.0이 도움이 될 것 같아요. xsl 2를 사용하여 XML 데이터를 그룹화하고 정렬하는 데 필요한 문서가 있습니다.0 :

관련 문제