|
-
Jul 5th, 2005, 05:03 AM
#1
Thread Starter
PowerPoster
Last edited by Pc_Madness; Jul 7th, 2005 at 02:38 AM.
Don't Rate my posts.
-
Jul 5th, 2005, 09:32 AM
#2
Re: Parsing XML for noobs?
I think DOM XML is quite simple to use, especially with XPath to help you navigate. (DOM navigation is usually quite the horror.) If you don't know XPath, look at the W3Schools tutorial.
I'll post the simplified constructor of a class that I've used to parse a TV programme.
Here's the XML:
Code:
<schedule>
<day date="20050620">
<station id="at_orf1">
<programme start="0010" end="0400" type="film" detailid="flug_534_tod_ueber_den_wolken-USA-2001"/>
<programme start="0410" end="0600" type="series" detailid="die_simpsons-USA-1989" episode="01x02"/>
<programme start="0610" end="1100" type="show" title="Der Ganze Vormittag Mit Confetti"/>
<programme start="1110" end="1200" type="news" title="Newssplash"/>
<programme start="1210" end="1600" type="series" detailid="dawsons_creek-USA-1998" episode="01x03"/>
<programme start="1610" end="1700" type="news" title="Newssplash"/>
<programme start="1710" end="1900" type="series" detailid="malcom_mittendrinn" episode="01x03"/>
<programme start="1900" end="2000" type="series" detailid="die_simpsons-USA-1989" episode="01x11"/>
<programme start="2015" end="2400" type="film" detailid="notting_hill-UK-1999"/>
</station>
<station id="at_orf2">
<programme start="0000" end="0130" type="news" title="Zeit im Bild 3"/>
<programme start="0130" end="0500" type="show" title="Show von Gestern"/>
<programme start="0500" end="0700" type="news" title="Morgenschmarrn"/>
<programme start="0700" end="1200" type="series" title="Reich und Lang"/>
<programme start="1200" end="1400" type="news" title="Viel Zeit im Bild"/>
<programme start="1400" end="1800" type="talk" title="Die Endlose Barbara Karlich Show"/>
<programme start="1800" end="2015" type="news" title="Noch Mehr Zeit im Bild"/>
<programme start="2015" end="2400" type="docu" title="Universum" subtitle="Das Verrinnen der Zeit"/>
</station>
</day>
</schedule>
The constructor looks like this:
Code:
function XmlSchedule(&$dom, $nodeset = false)
{
if($nodeset === false) {
$this->xpathctx =& xpath_new_context($dom);
$xpr = "//programme";
$res = @$this->xpathctx->xpath_eval($xpr);
$this->nodeset = $res->nodeset;
} else {
$this->xpathctx =& $dom;
$this->nodeset = $nodeset;
}
}
The $dom parameter, provided that $nodeset is false, is a DOM XML dom cretated with domxml_open_file. This just initializes the schedule. More interesting is getAt, which looks up a programme based on time and station.
Code:
function getAt($station, $timestamp)
{
$date = $timestamp['date'];
$time = $timestamp['time'];
$stationid = $station->getId();
$xpr = "//day[number(@date) = $date]//station[@id='$stationid']".
"//programme[number(@start) <= $time and number(@end) >= $time]";
$res = @$this->xpathctx->xpath_eval($xpr);
if(isset($res->nodeset[0]) &&
array_obj_search_p($res->nodeset[0], $this->nodeset, '0') !== false)
{
return new XmlProgramme($res->nodeset[0]);
} else {
return null;
}
}
The real work is done by the XmlProgramme constructor, which turns this node into actual data.
Code:
function XmlProgramme(&$node)
{
$types = getTypes();
$this->type = $types->get($node->get_attribute('type'));
$this->extendedAttributes = array();
$known = array( 'start' => true,
'end' => true,
'type' => true,
'title' => true,
'detailid' => true
);
foreach($node->attributes() as $attr) {
if(!$known[$attr->name()]) {
$this->extendedAttributes[$attr->name()] = $attr->value();
}
}
if($this->type->hasDetail()) {
$this->detailid = $node->get_attribute('detailid');
} else {
$this->detailid = "";
}
$this->title = $node->get_attribute('title');
if(!$this->title && $this->getDetail()) {
$detail = $this->getDetail();
$this->title = $detail->getTitle();
}
$this->blurb = getNodeContent(getChildNode($node, 'blurb'));
if(!$this->blurb && $this->getDetail()) {
$detail = $this->getDetail();
$this->blurb = $detail->getSummary();
}
$stations = getStations();
$parent = $node->parent_node();
$this->station = $stations->get($parent->get_attribute('id'));
$parent = $parent->parent_node();
$startdate = $parent->get_attribute('date');
$starttime = $node->get_attribute('start');
$endtime = $node->get_attribute('end');
$startday = substr($startdate, 6, 2);
$startmonth = substr($startdate, 4, 2);
$startyear = substr($startdate, 0, 4);
$starthour = substr($starttime, 0, 2);
$startminute = substr($starttime, 2, 2);
$startdate = mktime($starthour, $startminute, 0,
$startmonth, $startday, $startyear);
$this->unixtime = $startdate;
$endhour = substr($endtime, 0, 2);
$endminute = substr($endtime, 2, 2);
$enddate = mktime($endhour, $endminute, 0,
$startmonth, $startday, $startyear);
// Seems to wrap around daybreak.
if($enddate < $startdate) {
$enddate = strtotime('+1 day', $enddate);
}
$this->time['date'] = date('Ymd', $startdate);
$this->time['time'] = date('Hi', $startdate);
$this->length = ($enddate - $startdate) / 60;
$this->importance = 1;
$this->image = createImage($this->getExtendedAttributes());
if(!$this->image && $this->getDetail()) {
$detail = $this->getDetail();
$this->image = $detail->getImage();
}
}
getNodeContent and getChildNode are simple wrapper functions.
Code:
function getNodeContent($node)
{
if(!$node) {
return '';
}
$text = '';
$chs = $node->child_nodes();
foreach($chs as $ch) {
if($ch->node_type() == XML_ELEMENT_NODE) {
$text .= getNodeContent($ch);
} else {
$text .= $ch->node_value();
}
}
return $text;
}
function getChildNode($node, $name)
{
$chs = $node->child_nodes();
foreach($chs as $ch) {
if($ch->node_name() == $name) {
return $ch;
}
}
return null;
}
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|