. * * ***************************************************************************************************************************************************/ class XmlArray { var $Vals; var $Array; var $Error; /**************************************************************************************************************************************** * Function: XmlParser * - A generic XML to Array function */ function XmlArray($input, $return_errors = false) { // First parse into struct $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parse_into_struct($parser, $input, $this->Vals, $index); xml_parser_free($parser); //unset($input, $index); // Result specific parsers if ($this->Vals[0]['tag'] == "eSearchResult") $this->eSearch(); elseif ($this->Vals[0]['tag'] == "eSummaryResult") $this->eSummary(); elseif ($this->Vals[0]['tag'] == "PubmedArticleSet") $this->eFetch(); else { if ($return_errors) throw new Exception( "Unrecognised XML file." ); else { echo "

Fatal error: lib/XmlArray.php encountered an unfamiliar Xml file.

";
				echo str_replace("<", "<", $input);
				die();
			}
		}
	}

 	// _Internal: Remove recursion in result array
 	function _del_p(&$ary) {
 		foreach ($ary as $k => &$v) {
 			if ($k === "_p") unset($ary[$k]);
 			elseif (is_array($ary[$k])) $this->_del_p($ary[$k]);
 		        // Added JAD 24/5/08: Removes the _c/_v/_a when there's only one entry --
 		        //	makes the array easier to handle
 		        if (is_array($v) and (count($v) == 1) and isset($v['_v'])) $v = $v['_v'];
 			elseif (is_array($v) and (count($v) == 1) and isset($v['_c'])) $v = $v['_c'];
			
			/*
 		        if (is_array($v)) {
 		        	if (empty($v['_c']) and empty($v['_a']) and !empty($v['_v'])) $v = $v['_v'];
 		        	elseif (empty($v['_c']) and !empty($v['_a']) and empty($v['_v'])) $v = $v['_a'];
 		        	elseif (!empty($v['_c']) and empty($v['_a']) and empty($v['_v'])) $v = $v['_c'];
				
 		        	elseif (empty($v['_v']) and !empty($v['_c']) and !empty($v['_a'])) {
					if (is_array($v['_a']) and (count($v['_a']) == 1)) foreach ($v['_a'] as $l => $x) { $v = array($x => $v['_c']); }
					elseif (!is_array($v['_a'])) $v = array($v['_a'] => $v['_c']);
 		        	}
 		        	elseif (!empty($v['_v']) and empty($v['_c']) and !empty($v['_a'])) {
					if (is_array($v['_a']) and (count($v['_a']) == 1)) foreach ($v['_a'] as $l => $x) { $v = array($x => $v['_v']); }
					elseif (!is_array($v['_a'])) $v = array($v['_a'] => $v['_v']);
 		        	}
  			}
  			if ((empty($k) OR is_numeric($k)) and is_array($v) and (count($v) == 1)) {
  				foreach ($v as $l => $w) { 
  					if (isset($ary[$l])) {
  						if (is_array($ary[$l])) $ary[$l][] = $w;
  						else $ary[$l] = array($ary[$l], $w);
  					}
  					else $ary[$l] = $w;
  				}
  				unset($ary[$k]);
  			}
  			*/
 		}
 	}
	
	function eSearch()
	{ 
 		// From http://mysrc.blogspot.com/2007/02/php-xml-to-array-and-backwards.html
 		$mnary=array();
 		$ary=&$mnary;
 	    	foreach ($this->Vals as $r) {
			$t=$r['tag'];
 	    		if ($t == "Item" and !empty($r['attributes'])) { 
 	    			$t = $r['attributes']['Name'];
 	    			unset($r['attributes']['Name']);
 	    			if (!empty($r['attributes']['Type'])) unset($r['attributes']['Type']);
 			}
			if ($r['type']=='open') {
				if (isset($ary[$t])) {
					if (isset($ary[$t][0])) $ary[$t][]=array(); else $ary[$t]=array($ary[$t], array());
					$cv=&$ary[$t][count($ary[$t])-1];
				} 
 	    	        	else $cv=&$ary[$t];
				if (isset($r['attributes'])) {foreach ($r['attributes'] as $k=>$v) $cv['_a'][$k]=$v;}
				$cv['_c']=array();
				$cv['_c']['_p']=&$ary;
				$ary=&$cv['_c'];
			} 
 	    	    	elseif ($r['type']=='complete') {
				if (isset($ary[$t])) { // same as open
					if (isset($ary[$t][0])) $ary[$t][]=array(); else $ary[$t]=array($ary[$t], array());
					$cv=&$ary[$t][count($ary[$t])-1];
				} 
 	    	        	else $cv=&$ary[$t];
				if (isset($r['attributes'])) {foreach ($r['attributes'] as $k=>$v) $cv['_a'][$k]=$v;}
				$cv['_v']=(isset($r['value']) ? $r['value'] : '');
			} 
			elseif ($r['type']=='close') {
				$ary=&$ary['_p'];
			}
 	    	}
 	    	unset($this->Vals);
 	    	$this->_del_p($mnary);
 		$this->Array = $mnary['eSearchResult'];
 		
 		// Make sure the IDlist is in array form, even if it only has one item
		if (isset($this->Array['IdList']['Id'])) {
			if (!is_array($this->Array['IdList']['Id'])) $this->Array['IdList']['Id'] = array($this->Array['IdList']['Id']);
			$this->Array['IdList'] = $this->Array['IdList']['Id'];
 		}
 	}
 	
 	function eSummary()
 	{
 		$mnary=array();
 		$ary=&$mnary;
 	    	foreach ($this->Vals as $r) {
 			$t=$r['tag'];
 	    		if ($t == "Item" and !empty($r['attributes'])) { 
 	    			$t = $r['attributes']['Name'];
 	    			unset($r['attributes']['Name']);
 	    			if (!empty($r['attributes']['Type'])) unset($r['attributes']['Type']);
 			}
 			if ($r['type']=='open') {
 				if (isset($ary[$t])) {
 					if (isset($ary[$t][0])) $ary[$t][]=array(); else $ary[$t]=array($ary[$t], array());
 					$cv=&$ary[$t][count($ary[$t])-1];
 				} 
 				else $cv=&$ary[$t];
 				if (isset($r['attributes'])) {foreach ($r['attributes'] as $k=>$v) $cv['_a'][$k]=$v;}
 				$cv['_c']=array();
 				$cv['_c']['_p']=&$ary;
 				$ary=&$cv['_c'];
 			} 
 			elseif ($r['type']=='complete') {
	 			if (isset($ary[$t])) { // same as open
	 				if (isset($ary[$t][0])) $ary[$t][]=array(); else $ary[$t]=array($ary[$t], array());
					$cv=&$ary[$t][count($ary[$t])-1];
 				} 
 				else $cv=&$ary[$t];
 				if (isset($r['attributes'])) {foreach ($r['attributes'] as $k=>$v) $cv['_a'][$k]=$v;}
 				$cv['_v']=(isset($r['value']) ? $r['value'] : '');
 			} 
 			elseif ($r['type']=='close') {
 				$ary=&$ary['_p'];
 			}
 		}
 	    	unset($this->Vals);
 	    	$this->_del_p($mnary);	

		// Catch errors
		if (isset($mnary['eSummaryResult']['ERROR'])) {
			$this->Error = $mnary['eSummaryResult']['ERROR'];
			throw new Exception(  $mnary['eSummaryResult']['ERROR'] );
		}

 		// eSummary specific cleanup -- handle sinlgle item records
 		if (!isset($mnary['eSummaryResult']['DocSum'][0]) and isset($mnary['eSummaryResult']['DocSum']['Id'])) $mnary['eSummaryResult']['DocSum'] = array($mnary['eSummaryResult']['DocSum']);
 		foreach ($mnary['eSummaryResult']['DocSum'] as $DocSum) {
 			$this->Array['DocSum'][$DocSum['Id']] = $DocSum;
 		}
 	}

 	function eFetch()
 	{
 		// Array of tags for which Attribs can be ignored
 		$AttribOveride = array('MedlineCitation', 'Article', 'ISSN', 'JournalIssue', 'AuthorList', 'Author');
 		$UseAttrib = array(
 			"ArticleId" => "IdType",
 			"PubMedPubDate" => "PubStatus",
 		);
 		
 		$mnary=array();
 		$ary=&$mnary;
 	    	foreach ($this->Vals as $r) {
 			$t=$r['tag'];
 			$AO = false;
 			if (in_array($t, $AttribOveride)) $AO = true;
 			if ($r['type']=='open') {
 				if (isset($UseAttrib[$t]) and !empty($r['attributes'][$UseAttrib[$t]])) {
 					$t = $r['attributes'][$UseAttrib[$t]];
 					$AO = true;
 				}
 				if (isset($ary[$t])) {
 					if (isset($ary[$t][0])) $ary[$t][]=array(); else $ary[$t]=array($ary[$t], array());
 					$cv=&$ary[$t][count($ary[$t])-1];
 				} 
 				else $cv=&$ary[$t];
 				if (isset($r['attributes']) and !$AO) {foreach ($r['attributes'] as $k=>$v) $cv['_a'][$k]=$v;}
 				$cv['_c']=array();
 				$cv['_c']['_p']=&$ary;
 				$ary=&$cv['_c'];
 			} 
 			elseif ($r['type']=='complete') {
 				if (isset($UseAttrib[$t]) and !empty($r['attributes'][$UseAttrib[$t]])) {
 					$t = $r['attributes'][$UseAttrib[$t]];
 					$AO = true;
 				}
 				if (isset($ary[$t])) { // same as open
	 				if (isset($ary[$t][0])) $ary[$t][]=array(); else $ary[$t]=array($ary[$t], array());
					$cv=&$ary[$t][count($ary[$t])-1];
 				} 
 				else $cv=&$ary[$t];
 				if (isset($r['attributes']) and !$AO) { foreach ($r['attributes'] as $k=>$v) $cv['_a'][$k]=$v; }
 				$cv['_v']=(isset($r['value']) ? $r['value'] : '');
 			} 
 			elseif ($r['type']=='close') {
 				$ary=&$ary['_p'];
 			}
 		}
 	    	unset($this->Vals);
 	    	$this->_del_p($mnary);
 	    	$this->_tidy_eFetch($mnary);
 		$this->Array = $mnary['PubmedArticleSet'];
 		if (!isset($this->Array['PubmedArticle'][0]) and isset($this->Array['PubmedArticle']['MedlineCitation'])) $this->Array['PubmedArticle'] = array($this->Array['PubmedArticle']);
 	}
 	function _tidy_eFetch(&$ary) {
 		foreach ($ary as $k => &$v) {
 		        if (!empty($v['AuthorList']['Author'])) { 		        	
 		        	$Authors = $v['AuthorList']['Author'];
 		        	unset($v['AuthorList']['Author']);

 		        	if (isset($Authors[0])) {
 		        		foreach ($Authors as $Author) {
 		        			if (!empty($Author['LastName'])) $ShortName = $Author['LastName'] . " " . (isset($Author['Initials']) ? $Author['Initials'] : '$ERR$');
 		        			elseif (!empty($Author['CollectiveName'])) $ShortName = $Author['CollectiveName'];
 		        			$v['AuthorList'][$ShortName] = $Author;
 		        		}
 		        	}
 		        	else {
					if (!empty($Authors['LastName'])) $ShortName = $Authors['LastName'] . " " . $Authors['Initials'];
 		        		elseif (!empty($Authors['CollectiveName'])) $ShortName = $Authors['CollectiveName'];
 		        		$v['AuthorList'][$ShortName] = $Authors; 		        	
 		        	}
 		        }
 			elseif (is_array($ary[$k])) $this->_tidy_eFetch($ary[$k]);
 			if (isset($v['Language'])) $v['Language'] = strtoupper($v['Language']);
 		} 	
 	}
}

?>