webmanager
asked on
How to sort an XML file by "title" using PHP
Hi there,
I have an XML file with about 1000 entries in it.
The XML is formatted similar to this:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmls="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<title>Programs</title>
<loc>programs.php</loc>
<changefreq>always</change freq>
<priority>0.9</priority>
</url>
<url>
<title>Training</title>
<loc>training.php</loc>
<changefreq>daily</changef req>
<priority>0.8</priority>
</url>
<url>
<title>College</title>
<loc>college.php</loc>
<changefreq>daily</changef req>
<priority>0.8</priority>
</url>
<url>
<title>Academic</title>
<loc>academic.php</loc>
<changefreq>daily</changef req>
<priority>0.7</priority>
</url>
<url>
<title>University</title>
<loc>University.php</loc>
<changefreq>daily</changef req>
<priority>0.7</priority>
</url>
<url>
<title>Education</title>
<loc>education.php</loc>
<changefreq>daily</changef req>
<priority>0.8</priority>
</url>
<url>
<title>Apply now</title>
<loc>apply.php</loc>
<changefreq>daily</changef req>
<priority>0.7</priority>
</url>
<url>
<title>Policies</title>
<loc>policies.php</loc>
<changefreq>daily</changef req>
<priority>0.7</priority>
</url>
</urlset>
My current PHP code looks like this:
<?php
$xml_file = new SimpleXMLElement('sitemap. xml', null, true);
echo '<ul>';
foreach ($xml_file->url as $itemChild) {
echo '<li><a href="' . $itemChild->loc . '">' . $itemChild->title . "</a></li>\n";
}
echo '</ul>';
?>
I want to sort the XML by the title attribute, and at each new letter in the alphabet, have a new list started. Basically, I want to create an automated A-Z index listing.
I'm new to XML, so I'm not sure what to do here.
I have an XML file with about 1000 entries in it.
The XML is formatted similar to this:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmls="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<title>Programs</title>
<loc>programs.php</loc>
<changefreq>always</change
<priority>0.9</priority>
</url>
<url>
<title>Training</title>
<loc>training.php</loc>
<changefreq>daily</changef
<priority>0.8</priority>
</url>
<url>
<title>College</title>
<loc>college.php</loc>
<changefreq>daily</changef
<priority>0.8</priority>
</url>
<url>
<title>Academic</title>
<loc>academic.php</loc>
<changefreq>daily</changef
<priority>0.7</priority>
</url>
<url>
<title>University</title>
<loc>University.php</loc>
<changefreq>daily</changef
<priority>0.7</priority>
</url>
<url>
<title>Education</title>
<loc>education.php</loc>
<changefreq>daily</changef
<priority>0.8</priority>
</url>
<url>
<title>Apply now</title>
<loc>apply.php</loc>
<changefreq>daily</changef
<priority>0.7</priority>
</url>
<url>
<title>Policies</title>
<loc>policies.php</loc>
<changefreq>daily</changef
<priority>0.7</priority>
</url>
</urlset>
My current PHP code looks like this:
<?php
$xml_file = new SimpleXMLElement('sitemap.
echo '<ul>';
foreach ($xml_file->url as $itemChild) {
echo '<li><a href="' . $itemChild->loc . '">' . $itemChild->title . "</a></li>\n";
}
echo '</ul>';
?>
I want to sort the XML by the title attribute, and at each new letter in the alphabet, have a new list started. Basically, I want to create an automated A-Z index listing.
I'm new to XML, so I'm not sure what to do here.
By the way, the sxiToArray / xml2array code is a modified version of the code found on the manual page for SimpleXMLIterator.
ASKER
How do I pull the XML file in from an external file. I need to keep it outside. I tried this... but no luck...
$xmlString = 'include("sitemap.xml")';
Yes, the php and xml files are in the same directory
$xmlString = 'include("sitemap.xml")';
Yes, the php and xml files are in the same directory
ASKER
gr8gonzo, that doesn't work...
this does though.
$xmlString = file_get_contents("sitemap .xml");
Having said that, the content is just being dumped as an array... I need it in UL's, and a new UL for each letter of the alphabet. So all the title's starting with A are in the same UL,then another for B's, etc.
this does though.
$xmlString = file_get_contents("sitemap
Having said that, the content is just being dumped as an array... I need it in UL's, and a new UL for each letter of the alphabet. So all the title's starting with A are in the same UL,then another for B's, etc.
Here is an example of how I "sorted" some XML. It's not pretty, but you may be able to apply the concepts to your needs.
Grouping the output into HTML <ul> blocks really should be posted as a separate question. It's not hard - you just keep the "old letter" and compare to the "new letter" - when that changes, you are in a new <ul> bock and you create the appropriate tags.
best to all, ~Ray
Grouping the output into HTML <ul> blocks really should be posted as a separate question. It's not hard - you just keep the "old letter" and compare to the "new letter" - when that changes, you are in a new <ul> bock and you create the appropriate tags.
best to all, ~Ray
<?php // RAY_sort_XML_2.php
error_reporting(E_ALL);
echo "<pre>\n"; // READABILITY
// CONSUME XML AND REPORT IT OUT IN A SORTED ORDER
// TEST DATA WRAPPED IN A REASONABLE XML PACKAGE
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<Package>
<ALPHA ID="1">
<NAME>Boston</NAME>
<DATE>10/30/2009 3:45:00 PM</DATE>
</ALPHA>
<ALPHA ID="1">
<NAME>LA</NAME>
<DATE>10/29/2009 3:45:00 PM</DATE>
</ALPHA>
<ALPHA ID="1">
<NAME>Miami</NAME>
<DATE>10/31/2009 3:45:00 PM</DATE>
</ALPHA>
<ALPHA ID="2">
<NAME>Paris</NAME>
<DATE>10/27/2009 3:45:00 PM</DATE>
</ALPHA>
<ALPHA ID="2">
<NAME>London</NAME>
<DATE>10/24/2009 3:45:00 PM</DATE>
</ALPHA>
<ALPHA ID="2">
<NAME>Madrid</NAME>
<DATE>10/30/2009 3:45:00 PM</DATE>
</ALPHA>
</Package>';
// MAKE AN OBJECT
$obj = SimpleXML_Load_String($xml);
// VISUALIZE THE OBJECT
// var_dump($obj);
// ITERATE OVER THE OBJECT TO INJECT A SORT CODE
foreach ($obj->ALPHA as $thing)
{
// CREATE AN IDENTITY FOR THE OBJECT
$object_id = md5(serialize($thing));
// INJECT THE ID INTO THE OBJECT
$thing->ObjectID = $object_id;
// GET THE ATTRIBUTE ID
$sort_attr = (string)$thing["ID"];
// PRODUCE A SORTABLE ISO8601 DATE
$sort_date = date('c', strtotime($thing->DATE));
// CREATE ARRAYS THAT WE CAN SORT
$attr_array[$object_id] = $sort_attr;
$date_array[$object_id] = $sort_date;
// SORT ASCENDING BY ATTR ID AND DESCENDING BY DATE
// MAN PAGE: http://us2.php.net/manual/en/function.arsort.php
asort($attr_array);
arsort($date_array);
}
var_dump($obj);
var_dump($attr_array);
var_dump($date_array);
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Wizard,
I'll take a look at the code you suggested.
As for me asking something that wasn't in the original... I did ask in the original (at the end)..
"I want to sort the XML by the title attribute, and at each new letter in the alphabet, have a new list started. Basically, I want to create an automated A-Z index listing."
:-)
I'll take a look at the code you suggested.
As for me asking something that wasn't in the original... I did ask in the original (at the end)..
"I want to sort the XML by the title attribute, and at each new letter in the alphabet, have a new list started. Basically, I want to create an automated A-Z index listing."
:-)
That's true. It's just that usually that type of information is provided as context / the end goal (which helps us ask the question listed in the title). :-)
Let me know how the code works.
Let me know how the code works.
ASKER
Thanks.
I was able to create a way to put in the section titles fairly easily... I just needed to stop looking at the code for a day. :-)
Thanks!
I was able to create a way to put in the section titles fairly easily... I just needed to stop looking at the code for a day. :-)
Thanks!
Open in new window