2013-04-12 4 views
1

У меня есть проблема с моим кодом на данный момент, и я надеюсь, что вы можете мне помочь.Экспорт XML из mySQL с PHP

Первый из рабочих таблиц

SELECT artist, album, song 
FROM artist 
LEFT JOIN album 
on artist.artist_ID = album.artist_ID 
LEFT JOIN song 
on album.album_ID = song.album_ID 
ORDER BY artist.artist, album.album_ID, song.song_ID 

Im пытаются экспортировать в XML с помощью PHP, так им создавая XML непосредственно в документе, так что я просто нажать на ссылку для просмотра и доступа к XML. Но проблема заключается в том, что песня не складывается под альбом. Вместо этого они делают это:

<music> 
<artist name="$artist1"> 
    <album name="$album1"> 
    <song>$song1</song> 
    </album> 
</artist> 
</music> 
<music> 
<artist name="$artist1"> 
    <album name="$album1"> 
    <song>$song2</song> 
    </album> 
</artist> 
</music> 

Я хочу, чтобы затем укладывать так:

<music> 
<artist name="$artist1"> 
    <album name="$album1"> 
    <song>$song1</song> 
    <song>$song2</song> 
    <song>$song3</song> 
    </album> 
</artist> 
</music> 

Это PHP-код я использую в данный момент экспортировать в XML, что-то здесь не работают. Я пытался исправить это последние 12 часов без везения.

$export = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; 
$export="<myTunes>"; 

while($row = mysqli_fetch_array($result)) 
{ 
    $export.="<music>"; 
    $artist=$row["artist"]; 
    $album=$row["album"]; 
    $song=$row["song"]; 

    $export.=" <artist name='$artist'> 
        <album name='$album'> 
         <song>$song</song> 
        </album> 
       </artist>"; 
    $export.="</music>"; 
} 
$export.="</myTunes>"; 

file_put_contents("export.xml", $export); 
echo "<a href='export.xml' target='_blank'>Export database as XML</a>"; 

Пожалуйста, помогите, если вы можете, я начну раздумывать здесь. С наилучшими пожеланиями, Chris

+1

Вам следует рассмотреть возможность использования 'DomDocument' или чего-то подобного для обработки фактического вывода XML. Манипулирование строк напрямую делает ваш код крайне уродливым, а получение XML-документа с замечательным отступом является сложным. –

+0

Я согласен, его очень сложно, если я хочу собрать всю песню под альбом. его легкость, если у меня есть элементы uniq в каждой строке. Я посмотрю, как работает «DomDocuments» и посмотрю, могу ли я это понять, спасибо за подсказку – user2272544

+0

Не пишите это самостоятельно. Это уже сделано. См. [XML_Query2XML] (http://pear.php.net/package/XML_Query2XML), а также документация конечного пользователя: http://query2xml.sourceforge.net/docs/ - Ваша выгода: пример, который дает автор, - это * очень похожая вещь: художники и альбомы. http://query2xml.sourceforge.net/docs/html/XML_Query2XML/tutorial_XML_Query2XML.pkg.html#x_to_n –

ответ

3

Я предлагаю другой подход, который приведет к XML, который вы хотите.
1. Я буду использовать XMLWriter, который поставляется с PHP, и
2. Опираясь на запрос базы данных довольно часто. Переход к базе данных часто накладывает некоторую нагрузку на ваш db-сервер, что плохо, если вы создаете эти XML-файлы каждую минуту или около того, или если многие пользователи делают это в одно и то же время, это нормально, если вы делаете это один раз в в то время как :-)
3. Я буду обращаться к базе данных, используя PDO вместо тех старых и ржавых mysql_*-functions, используя prepared statements, что является отличной функцией.

// setting up PDO 
$dbLocation = 'mysql:dbname=db001;host=localhost'; 
$dbUser = 'user'; 
$dbPass = 'password'; 
$db = new PDO($dbLocation, $dbUser, $dbPass); 

// prepare all queries... 
$dbArtists = $db->prepare("SELECT * FROM artist"); 
$dbAlbums = $db->prepare("SELECT * FROM album WHERE artist_ID=:artist_id"); 
$dbSongs = $db->prepare("SELECT * FROM song WHERE album_ID=:album_id"); 

// fetch all artists 
$dbArtists->execute(); 
$artists=$dbArtists->fetchAll(PDO::FETCH_ASSOC); 


$x=new XMLWriter(); 
$x->openMemory(); 
$x->startDocument('1.0','UTF-8'); 
$x->startElement('music'); 

foreach ($artists as $artist) { 

    $x->startElement('artist'); 
    $x->writeAttribute('name',$artist['artist']); 

    // fetch all albums of this artist   
    $dbAlbums->execute(array(':artist_id' => $artist['artist_id'])); 
    $albums = $dbAlbums->fetchAll(PDO::FETCH_ASSOC); 

    foreach ($albums as $album) { 

     $x->startElement('album'); 
     $x->writeAttribute('name',$album['album']); 

     // fetch all songs from this album    
     $dbSongs->execute(array(':album_id' => $album['album_id'])); 
     $songs = $dbSongs->fetchAll(PDO::FETCH_ASSOC); 

     foreach ($songs as $song) { 

      $x->startElement('song'); 
       $x->text($song['song']); 
      $x->endElement(); // song 
     } // foreach $songs 

     $x->endElement(); // album 
    } // foreach $albums 

    $x->endElement(); // artist 
} // foreach $artists 

$x->endElement(); // music 
$x->endDocument(); 
$xml = $x->outputMemory(); 

// now save $xml to a file etc. 
1

Код ниже отражает только общую идею одного из алгоритмов и, конечно, должен быть реорганизован в производственной версии.

$export = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; 
$export .= "<myTunes>"; 
$export .= "<music>"; 

$lastArtist = $lastAlbum = null; 

while($row = mysqli_fetch_array($result)) 
{ 
    $artist=$row["artist"]; 
    $album=$row["album"]; 
    $song=$row["song"]; 

    if(($lastArtist == null) and ($lastAlbum == null)) 
     $export.="<artist name='$artist'><album name='$album'>"; 
    else 
    { 
     if($artist != $lastArtist) 
      $export.="</artist><artist name='$artist'>"; 

     if($album != $lastAlbum) 
      $export.="</album><album name='$album'>"; 
    } 

    $export.=" <song>$song</song>"; 

    $lastArtist = $artist; 
    $lastAlbum = $album; 
} 
$export.="</album></artist></music>"; 
$export.="</myTunes>"; 

file_put_contents("export.xml", $export); 
echo "<a href='export.xml' target='_blank'>Export database as XML</a>"; 
+0

Я пробовал это и пришел к выводу, что если я использую $ export внутри цикла if, я получаю сообщение об ошибке. Раньше я использовал что-то симулятивное, но потом теги отклоняли все неправильно. Как это ' <имя исполнителя = "$ artist1"> <название альбома = "$ album1"> $ SONG1 $ song2 ' – user2272544

0

Проблема заключается в том, что вы перебираете все свои результаты и записываете всю информацию с каждой итерацией.

Возможно, вы можете использовать два запроса. Первый, чтобы получить ваш художник и альбом, который вы можете зациклиться, а затем секунду, чтобы получить ваши песни, результаты которых также могут быть зациклированы внутри вашего внешнего цикла, чтобы добавить песни в качестве дочерних элементов в ваш элемент альбома.

Смежные вопросы