PHP ile Sıralama / Grup XML veri?

3 Cevap php

Ben discogs.com (XML)-API verileri kullanarak bir sayfa yapmaya çalışıyorum. Ben SimpleXML ile ayrıştırma oldum ve oldukça iyi çalışıyor ama bunu nasıl emin değilim bazı şeyler var.

İşte XML parçasıdır:

<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>

Ne ben ulaşmak istiyorum discogs bültenleri sunuyor nasıl similair şeydir: http://www.discogs.com/artist/Mics+Of+Fury aynı sürümü ayrılmakta sürümleri birlikte sıralanır nerede. (Benim linkte MOF Blend bkz.) Bu, diğer sürümleri özellikleri bir ana salınımını sahip Discogs yapılır. ne yazık ki bu bilgiler API veri mevcut değildir, bu yüzden aynı <title> etiketleri ile <release> düğümleri gruplayarak aynı şeyi yapmak, ya da bir bayrak eklemek istediğiniz <releases> o yoksa benzersiz bir <title>? Bunu yapmanın en iyi yolu iyi bir fikir?

ben de aynı tip-nitelik <release>-düğümleri (bültenleri çocuk) saymak mümkün olmadığını bilmek ister misiniz? gibi bu örnekte tipi "Ana" ile sayım bültenleri?

belki XMLReader veya XPath ile bu şeyler yapmak daha iyidir?

3 Cevap

You can use xsl(t) and php's XSLTProcessor.
In xslt 2.0 you could use something like

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

Unfortunately libxslt doesn't support this (at least the version used in the php.net win32 build of php 5.3.2 doesn't).
But you can use the 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 containing the xml document you provided.
And 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);

Ve (

-bölümünde Onlye) çıktı:

<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>

Şimdi, bu bir explaination çok değil. Ama belki size aramak için ne bazı ipuçları verir.

Geçenlerde ben nesnelerin HTML tabloları oluşturmak ve sıralamak için kullanabileceğiniz bir sınıf inşa etmişlerdir, burada ilişkilendirilebilir diziler sıralamak için yararlı olabilir, ondan bir statik bazı yöntemler vardır. Sadece fonksiyonları gibi yöntemleri kullanabilirsiniz yüzden self :: başvuru kaldırdık.

Kullanımı: $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;
    }

Ben XSLT 2.0, burada gruplama uygulayarak ve xsl 2.0 kullanarak XML veri sıralama için belgelendirmesi mümkün yardım olabilir sanırım: