Results 1 to 2 of 2

Thread: [Resolved]Parsing XML for noobs?

  1. #1

    Thread Starter
    PowerPoster Pc_Madness's Avatar
    Join Date
    Dec 2001
    Location
    Melbourne, Australia
    Posts
    2,765

    Resolved [Resolved]Parsing XML for noobs?

    Code:
    <timetable>
    	<day>
    		<name>Monday</name>
    		<subject>
    			<starttime>8</starttime>
    			<endtime>9</endtime>
    			<name>SIT202</name>
    			<type>Prac</type>
    			<room>LT1</room>
    		</subject>
    	</day>
    </timetable>
    Looked at about 10 parsers, all of them are super confusing, or just leave me with this array thats about 20 dimensions and I can't figure out how to navigate it properly. Basically just trying to do a Timetable app, 5 days, many subjects to each day.

    Does anyone have a really easy parser or link to a parser with some sample code? :/ I noticed PHP has SimpleXML, but it requires PHP 5.
    Last edited by Pc_Madness; Jul 7th, 2005 at 02:38 AM.
    Don't Rate my posts.

  2. #2
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594

    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
  •  



Click Here to Expand Forum to Full Width