【问题标题】:export XML from mySQL with PHP使用 PHP 从 mySQL 导出 XML
【发布时间】:2013-04-04 09:24:57
【问题描述】:

目前我的代码有点问题,希望您能帮我解决。

表格的第一个

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

我试图在 php 的帮助下将其导出为 XML,因此我直接在文档中创建 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>

这是我目前用来导出到 XML 的 PHP 代码,这里有些东西不起作用。 在过去的 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>";

如果可以的话,请帮忙,我在这里开始失去理智了。 最好的祝福, 克里斯

【问题讨论】:

  • 您应该考虑使用DomDocument 或类似的东西来处理实际的XML 输出。直接操作字符串会使您的代码变得极其丑陋,而获得缩进良好的 XML 文档具有挑战性。
  • 我同意,如果我想把专辑下的所有歌曲都堆叠起来真的很难。如果我在每一行都有 uniq 项目,这很容易.. 我会研究 DomDocuments 的工作原理,看看我是否能弄清楚,谢谢你的提示
  • 不要自己写。它已经完成了。请参阅XML_Query2XML,它还有最终用户文档:query2xml.sourceforge.net/docs - 您的好处:作者给出的示例非常相似:艺术家和专辑。 query2xml.sourceforge.net/docs/html/XML_Query2XML/…
  • 为什么还要费心格式化 XML 文件?考虑通过仅删除所有换行符/制表符/空格字符将节省多少带宽。除非出于某种原因,您希望人工编辑 XML 文件,这通常不是 XML 的用途。

标签: php mysql xml


【解决方案1】:

我会建议一种不同的方法来生成您想要的 XML。
1.我将使用PHP自带的XMLWriter,以及
2.依赖经常查询数据库。经常访问数据库会给您的数据库服务器带来一些负载,如果您每分钟左右创建这些 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.

【讨论】:

    【解决方案2】:

    下面的代码只反映了其中一种算法的大致思路,当然,它应该在生产版本中进行重构。

    $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>";
    

    【讨论】:

    • 我试过这个并得出结论,如果我在 if 循环中使用 $export ,我会得到一个错误。我之前确实使用过类似的东西,但后来标签都错了。像这样&lt;music&gt; &lt;artist name="$artist1"&gt; &lt;album name="$album1"&gt; &lt;song&gt;$song1&lt;/song&gt; &lt;/album&gt; &lt;/artist&gt; &lt;/music&gt; &lt;music&gt;&lt;song&gt;$song2&lt;/song&gt; &lt;/music&gt;
    【解决方案3】:

    问题似乎是您循环遍历所有结果并在每次迭代中写出所有信息。

    您可以考虑使用两个查询。第一个获取您可以循环的艺术家和专辑,然后第二个获取您的歌曲,其结果也可以在您的外部循环内循环,以将歌曲作为子元素添加到您的专辑元素。

    【讨论】:

      猜你喜欢
      • 2013-01-05
      • 1970-01-01
      • 2016-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      • 2017-06-07
      相关资源
      最近更新 更多