summaryrefslogtreecommitdiff
blob: 4e363463894fb679bad36edaddae2376a76fb19f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?

class XMLParser {

	function start_handler($parser, $name, $attr) {
		$tmpxmlpath = $this->xmlpath ? explode("/", $this->xmlpath) : array();
		$tmpxmlpath[] = $name;
		$this->xmlpath = implode("/", $tmpxmlpath);
		$this->attrs[] = $attr;
	}

	function end_handler($parser, $name) {
		if(array_key_exists($this->xmlpath, $this->xmlpaths)) {
			if($this->values[$this->xmlpaths[$this->xmlpath]]) {
				$this->chardata = trim($this->chardata);
				switch($this->values[$this->xmlpaths[$this->xmlpath]]['type']) {
					case 'string':
					case 'uri':
						break;
					case 'bool':
						$this->chardata = $this->chardata == "True" ? 1 : 0;
						break;
					case 'int':
						$this->chardata = intval($this->chardata);
						break;
					case 'array':
						$this->chardata = explode(" ", $this->chardata);
						if(count($this->chardata) == 1 && !$this->chardata[0]) $this->chardata = array();
						break;
				}
				$this->set($this->xmlpaths[$this->xmlpath], $this->chardata);
			} else {
				call_user_func(array($this, $this->xmlpaths[$this->xmlpath]), trim($this->chardata), array_pop($this->attrs));
			}
		} else {
			# This probably isn't good
		}
		$this->chardata = "";
		$tmpxmlpath = explode("/", $this->xmlpath);
		array_pop($tmpxmlpath);
		$this->xmlpath = implode("/", $tmpxmlpath);
	}

	function char_handler($parser, $data) {
		$this->chardata .= $data;
	}

	function parse($xmlfile) {
		$this->parser = xml_parser_create();
		xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
		xml_set_object($this->parser, $this);
		xml_set_element_handler($this->parser, 'start_handler', 'end_handler');
		xml_set_character_data_handler($this->parser, 'char_handler');
		$this->attrs = array();
		$this->xmlpath = "";
		$this->chardata = "";
		$file_contents = file_get_contents($xmlfile);
		if(!$file_contents) return false;
		xml_parse($this->parser, $file_contents);
		xml_parser_free($this->parser);
		return true;
	}

	function get($name) {
		return $this->values[$name]['value'];
	}

	function set($name, $value) {
		$this->values[$name]['value'] = $value;
	}

	function _serialize($xmlroot) {
		$this->xmldoc = "<?xml version=\"1.0\"?>\n";
		$this->xmldoc .= "<{$xmlroot}>\n";

		foreach($this->values as $name => $value) {
			if($value['serialize_func']) {
				call_user_func(array($this, $value['serialize_func']));
			} else {
				$xmlname = "";
				foreach($this->xmlpaths as $xmlpath => $valname) {
					if($name == $valname) {
						$tmpxmlpath = explode("/", $xmlpath);
						$xmlname = $tmpxmlpath[count($tmpxmlpath)-1];
						break;
					}
				}
				if(!$xmlname) continue;
				$data = $this->get($name);
				if($data) {
					switch($value['type']) {
						case 'string':
						case 'uri':
							$this->xmldoc .= sprintf("\t<%s>\n\t\t%s\n\t</%s>\n", $xmlname, $data, $xmlname);
							break;
						case 'bool':
							$this->xmldoc .= sprintf("\t<%s>\n\t\t%s\n\t</%s>\n", $xmlname, $data ? "True" : "False", $xmlname);
							break;
						case 'int':
							$this->xmldoc .= sprintf("\t<%s>\n\t\t%d\n\t</%s>\n", $xmlname, intval($data), $xmlname);
							break;
						case 'array':
							$this->xmldoc .= sprintf("\t<%s>\n\t\t%s\n\t</%s>\n", $xmlname, implode(" ", $data), $xmlname);
							break;
					}
				} else {
					$this->xmldoc .= sprintf("\t<%s/>\n", $xmlname);
				}
			}
		}

		$this->xmldoc .= "</{$xmlroot}>\n";
		return $this->xmldoc;
	}
}

?>