Reputation: 321
I need to sort table data that I've taken from an xml
and I need to sort the table based on the Product Name. I've tried using the sortTable()
function from w3school
but it won't work. I've tried using the usort
method, but I can only sort it using the item's attribute and I don't know how to send the xml
data to html
after it has been sorted out. Really need help here.
This is the xml
code:
<channel>
<item id='123'>
<g:productname>67510BS Black Shirt</g:productname>
<g:price>20</g:price>
<g:stock>190</g:stock>
</item>
<item id='122'>
<g:productname>10973JU White Shirt</g:productname>
<g:price>23</g:price>
<g:stock>59</g:stock>
</item>
<item id='103'>
<g:productname>12390IJ Yellow Shirt</g:productname>
<g:price>18</g:price>
<g:stock>27</g:stock>
</item>
<item id='89'>
<g:productname>12094OK Grey Shirt</g:productname>
<g:price>10</g:price>
<g:stock>0</g:stock>
</item>
<item id='200'>
<g:productname>98704OW Brown Shirt</g:productname>
<g:price>15</g:price>
<g:stock>54</g:stock>
</item>
</channel>
And this is the php code:
<?php
$document = new DOMDocument('1.0', 'UTF-8');
$document->formatOutput = true;
$document->preserveWhiteSpace = false;
$document->load('shirt.xml');
filterxml($document)
createhtml($document);
function filterxml($doc) {
$xpath = new DOMXPath($doc);
// Find the <item> nodes that has g:availability = Disabled or stock = 0, and then delete them
$nodes = $xpath->query("/rss/channel/item[(g:availability = 'Disabled') or (g:stock = 0)]");
// Remove the offending nodes from the DOM
for ($i = 0; $i < $nodes->length; $i++) {
$node = $nodes->item($i);
$node->parentNode->removeChild($node);
}
// ----------- THIS IS THE USORT THAT I'VE TRIED -----------
/* $listitem = $xpath->query('//item');
$items = iterator_to_array($listitem);
function sort_by_numeric_id_attr($a, $b) {
return (int) $a->getAttribute('id') - (int) $b->getAttribute('id');
}
usort($items, 'sort_by_numeric_id_attr');*/
}
function createhtml($doc) {
$html = new DOMDocument('1.0', 'UTF-8');
$html->preserveWhiteSpace = true;
$xpath = new DOMXPath($doc);
$num = 0;
$header = array (
'No.',
'Product Name',
'Price',
'Stock'
);
$htmltag = $html->appendChild($html->createElement('html'));
$body = $htmltag->appendChild($html->createElement('body'));
$body->setAttribute('onload', 'sortTable()');
$table = $body->appendChild($body->createElement('table'));
$table->setAttribute('id', 'productTable');
$row = $table->appendChild($html->createElement('tr'));
foreach($header as $label) {
$row
->appendChild($html->createElement('th'))
->appendChild($html->createTextNode($label));
}
foreach ($xpath->evaluate('//item') as $item) {
$row = $table->appendChild($html->createElement('tr'));
$num++;
$number = $row->appendChild($html->createElement('td', $num));
$prodName = $xpath->evaluate('string(g:productname)', $item);
$itemName = $row->appendChild($html->createElement('td', $prodName));
$itemName->setAttribute('width', '100px');
$price = $xpath->evaluate('number(g:price)', $item);
$row
->appendChild($html->createElement('td'))
->appendChild(
$html->createTextNode('$ ' . number_format($price, 0, '', '.') . ',-')
);
$stock = $xpath->evaluate('number(g:stock)', $item);
$stocktd = $row->appendChild($html->createElement('td', $stock));
$stocktd->setAttribute('width', '350px');
}
$script=<<<END
function sortTable() {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById('tabelProduk');
switching = true;
dir = 'asc';
while(switching) {
switching = false;
rows = table.getElementsByTagName('tr');
for (i=1; i<(rows.length-1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName('td')[n];
y = rows[i].getElementsByTagName('td')[n];
if(dir == 'asc') {
if(x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
else if (dir == 'desc') {
if (x.innerHTML.toLowercase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i+1], rows[i]);
switching = true;
switchcount++;
}
else {
if (switchcount == 0 && dir == 'asc') {
dir = 'desc';
switching = true;
}
}
}
}
END;
$scripttag = $htmltag->appendChild($html->createElement('script', $script));
$scripttag->setAttribute('type', 'text/javascript');
$html->formatOutput = true;
$htmlsave = $html->saveHtml();
file_put_contents('download/Shirt.html', $htmlsave);
}
}
?>
Upvotes: 1
Views: 472
Reputation: 41885
Another way to sort the product names is to import your $xpath
object into the usort
, then access the product name from there and use strcasecmp
for comparison.
Idea:
$items = iterator_to_array($listitem);
// sort by product name
usort($items, function($a, $b) use ($xpath) {
$product_name_a = $xpath->evaluate('string(g:productname/text())', $a);
$product_name_b = $xpath->evaluate('string(g:productname/text())', $b);
return strcasecmp($product_name_a, $product_name_b);
});
Note: I wouldn't create the html markup using DOMDocument though, I'll just create the table through strings.
Upvotes: 1