1<?php
2/********************************
3OSBib:
4A collection of PHP classes to manage bibliographic formatting for OS bibliography software
5using the OSBib standard.  Taken from WIKINDX (http://wikindx.sourceforge.net).
6
7Released through http://bibliophile.sourceforge.net under the GPL licence.
8Do whatever you like with this -- some credit to the author(s) would be appreciated.
9
10The XML parsing is indebted to code by Dante Lorenso at:
11http://www.devarticles.com/c/a/PHP/Converting-XML-Into-a-PHP-Data-Structure/
12
13If you make improvements, please consider contacting the administrators at bibliophile.sourceforge.net
14so that your improvements can be added to the release package.
15
16Mark Grimshaw 2005
17http://bibliophile.sourceforge.net
18********************************/
19
20class PARSEXML
21{
22	function PARSEXML()
23	{
24	}
25// Grab a complete XML entry
26	function getEntry($entries)
27	{
28// entries now elements in $entries array
29		foreach($entries as $entry)
30		{
31// create root node in node array
32			$this->nodeStack = array();
33			$this->startElement(NULL, 'ROOT', array());
34// complete $xmlString and parse it
35			$xmlString = "<style>" . $entry . "</style>";
36			$this->entries[] = $this->parse($xmlString);
37		}
38	}
39
40// This method starts the whole process
41	function extractEntries($fh)
42	{
43		$this->entries = array();
44            	while(!feof($fh))
45            	{
46			if(preg_match_all("/<style.*>(.*)<\/style>/Ui", trim(fgets($fh)), $startEntry))
47				$this->getEntry($startEntry[1]);
48           	}
49		if(empty($this->entries))
50			$this->entries = FALSE;
51		$info['name'] = $this->entries[0]['_ELEMENTS'][0]['_ELEMENTS'][0]['_DATA'];
52		$info['description'] = $this->entries[0]['_ELEMENTS'][0]['_ELEMENTS'][1]['_DATA'];
53		$info['language'] = $this->entries[0]['_ELEMENTS'][0]['_ELEMENTS'][2]['_DATA'];
54// Following added to later versions so need to check in case earlier version is being loaded into the editor.
55		if(array_key_exists(3, $this->entries[0]['_ELEMENTS'][0]['_ELEMENTS']))
56			$info['version'] = $this->entries[0]['_ELEMENTS'][0]['_ELEMENTS'][3]['_DATA'];
57		if(!array_key_exists(2, $this->entries[0]['_ELEMENTS']))
58		{
59			$common = $this->entries[0]['_ELEMENTS'][1]['_ELEMENTS'][0]['_ELEMENTS'];
60			array_shift($this->entries[0]['_ELEMENTS'][1]['_ELEMENTS']);
61			foreach($this->entries[0]['_ELEMENTS'][1]['_ELEMENTS'] as $array)
62				$types[] = $array;
63			$citation = array();
64		}
65		else
66		{
67			$citation = $this->entries[0]['_ELEMENTS'][1]['_ELEMENTS'];
68			$common = $this->entries[0]['_ELEMENTS'][2]['_ELEMENTS'][0]['_ELEMENTS'];
69			array_shift($this->entries[0]['_ELEMENTS'][2]['_ELEMENTS']);
70			foreach($this->entries[0]['_ELEMENTS'][2]['_ELEMENTS'] as $array)
71				$types[] = $array;
72		}
73		return array($info, $citation, $common, $types);
74	}
75
76	function parse($xmlString="")
77	{
78// set up a new XML parser to do all the work for us
79		$this->parser = xml_parser_create('UTF-8');
80		xml_set_object($this->parser, $this);
81		xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
82		xml_set_element_handler($this->parser, "startElement", "endElement");
83		xml_set_character_data_handler($this->parser, "characterData");
84// parse the data
85		xml_parse($this->parser, $xmlString);
86		xml_parser_free($this->parser);
87// recover the root node from the node stack
88		$rnode = array_pop($this->nodeStack);
89// return the root node _ELEMENTS array
90		return($rnode["_ELEMENTS"][0]);
91	}
92
93// create a node
94	function startElement($parser, $name, $attrs)
95	{
96		$node = array();
97		$node["_NAME"] = $name;
98		if(!empty($attrs) && ($name == "resource"))
99			$node["_ATTRIBUTES"] = $attrs;
100		$node["_DATA"] = "";
101		$node["_ELEMENTS"] = array();
102// add the new node to the end of the node stack
103		array_push($this->nodeStack, $node);
104	}
105
106	function endElement($parser, $name)
107	{
108// pop this element off the node stack.....
109		$node = array_pop($this->nodeStack);
110		$data = trim($node["_DATA"]);
111// (Don't store empty DATA strings and empty ELEMENTS arrays)
112//		if($data !== FALSE)
113//			$node["_DATA"] = $data;
114//		else
115//			unset($node["_DATA"]);
116//		if(empty($node["_ELEMENTS"]))
117//			unset($node["_ELEMENTS"]);
118// .....and add it as an element of the last node in the stack...
119		$lastnode = count($this->nodeStack);
120		array_push($this->nodeStack[$lastnode - 1]["_ELEMENTS"], $node);
121	}
122
123// Collect the data onto the end of the current chars.
124	function characterData($parser, $data)
125	{
126// add this data to the last node in the stack...
127		$lastnode = count($this->nodeStack);
128		$this->nodeStack[$lastnode - 1]["_DATA"] .= $data;
129	}
130}
131
132?>
133
134