我正在尝试使用discogs.com(XML)-API中的数据制作页面。我一直用simpleXML解析它并且它工作得很好但是有些东西我不知道该怎么做。
以下是XML的一部分:
<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>
我想要实现的是类似于discogs如何呈现版本的内容:http://www.discogs.com/artist/Mics+Of+Fury其中同一版本的不同版本被排序在一起。 (参见我的链接中的M.O.F Blend)这是在具有主要版本的discogs上完成的,其中包含其他版本的主要版本。遗憾的是,这些信息不存在于API数据中,所以我想通过将<release>
- 节点与相同的<title>
- 标签分组来做同样的事情,或者为{{1}添加一个标志没有唯一的<releases>
?有关最佳方法的任何好主意吗?
我还想知道是否可以计算具有相同类型属性的<title>
- 节点(发布的子节点)?比如在这个例子中计算版本为“Main”的版本?
使用XMLReader或XPath做这件事可能更好吗?
答案 0 :(得分:2)
您可以使用xsl(t)和php's XSLTProcessor 在xslt 2.0中,您可以使用类似
的内容<xsl:for-each-group select="release" group-by="title">
不幸的是libxslt不支持这个(至少在php 5.3.2的php.net win32版本中使用的版本不支持)。
但您可以使用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>
包含您提供的xml文档的test.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);
输出(只有&lt; table&gt; -part)是:
<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>
现在,这不是一个解释。但也许它会为你提供一些搜索内容的提示。
答案 1 :(得分: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 :(得分:0)