Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
 
3
/*
4
	This file is part of ActiveLink PHP XML Package (www.active-link.com).
5
	Copyright (c) 2002-2004 by Zurab Davitiani
6
 
7
	You can contact the author of this software via E-mail at
8
	hattrick@mailcan.com
9
 
10
	ActiveLink PHP XML Package is free software; you can redistribute it and/or modify
11
	it under the terms of the GNU Lesser General Public License as published by
12
	the Free Software Foundation; either version 2.1 of the License, or
13
	(at your option) any later version.
14
 
15
	ActiveLink PHP XML Package is distributed in the hope that it will be useful,
16
	but WITHOUT ANY WARRANTY; without even the implied warranty of
17
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
	GNU Lesser General Public License for more details.
19
 
20
	You should have received a copy of the GNU Lesser General Public License
21
	along with ActiveLink PHP XML Package; if not, write to the Free Software
22
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
*/
24
 
25
import("org.active-link.xml.Tag");
26
import("org.active-link.xml.Tree");
27
 
28
/**
29
  *	XML class provides a tree-like structure to read/write/modify XML
30
  *	@class		XML
31
  *	@package	org.active-link.xml
32
  *	@author		Zurab Davitiani
33
  *	@version	0.4.0
34
  *	@extends	Tree
35
  *	@requires	Tag, Tree, XMLBranch, XMLLeaf
36
  *	@see		Tree
37
  */
38
 
39
class XML extends Tree {
40
 
41
	// protected variables
42
	var $tag;
43
	var $pathSeparator;
44
 
45
	/**
46
	  *	If argument is an XML String it parses the string into XML object
47
	  *	If argument is a tag path, creates appropriate branches and tags
48
	  *	If argument is a simple string then sets that as a root tag name
49
	  *	@method		XML
50
	  *	@param		optional string argument
51
	  *	@returns	none
52
	  */
53
	function XML($argument = "") {
54
		$success = false;
55
		$this->Tree();
56
		$this->pathSeparator = "/";
57
		$this->tag = new Tag();
58
		if(is_string($argument)) {
59
			// if this is an XML string to be parsed
60
			if(strpos($argument, $this->tag->tagEndOpen) > 0 || strpos($argument, $this->tag->tagClose) > 0)
61
				$this->parseFromString($argument);
62
			// else if this is a tag path to be created
63
			elseif(strpos($argument, $this->pathSeparator) > 0) {
64
				$tags = explode($this->pathSeparator, $argument);
65
				$this->tag->setTagName($tags[0]);
66
				$this->setTagContent("", $argument);
67
			}
68
			else
69
				$this->tag->setTagName($argument);
70
			$success = true;
71
		}
72
		else
73
			$success = false;
74
		return $success;
75
	}
76
 
77
	/**
78
	  *	Adds another XML tree as a branch to the current XML object
79
	  *	@method		addXMLAsBranch
80
	  *	@param		object xml
81
	  *	@param		optional mixed id
82
	  *	@returns	true if successful, false otherwise
83
	  */
84
	function addXMLAsBranch($xml, $id = -1) {
85
		$success = false;
86
		if(is_object($xml) && strtolower(get_class($xml)) == "xml") {
87
			$newBranch = new XMLBranch();
88
			$newBranch->nodes = $xml->nodes;
89
			$newBranch->tag = $xml->tag;
90
			$success = $this->addXMLBranch($newBranch, $id);
91
		}
92
		return $success;
93
	}
94
 
95
	/**
96
	  *	Adds XML Branch to the current XML object
97
	  *	@method		addXMLBranch
98
	  *	@param		object xmlBranch
99
	  *	@param		optional mixed id
100
	  *	@returns	true if successful, false otherwise
101
	  */
102
	function addXMLBranch($xmlBranch, $id = -1) {
103
		$success = false;
104
		if(is_object($xmlBranch) && strtolower(get_class($xmlBranch)) == "xmlbranch") {
105
			$xmlBranch->setParentXML($this);
106
			$success = $this->addNode($id, $xmlBranch);
107
		}
108
		return $success;
109
	}
110
 
111
	/**
112
	  *	Adds XML Leaf to the current XML object
113
	  *	@method		addXMLLeaf
114
	  *	@param		object xmlLeaf
115
	  *	@param		optional mixed id
116
	  *	@returns	true if successful, false otherwise
117
	  */
118
	function addXMLLeaf($xmlLeaf, $id = -1) {
119
		$success = false;
120
		if(is_object($xmlLeaf) && strtolower(get_class($xmlLeaf)) == "xmlleaf") {
121
			$xmlLeaf->setParentXML($this);
122
			$success = $this->addNode($id, $xmlLeaf);
123
		}
124
		return $success;
125
	}
126
 
127
	/**
128
	  *	Retrieves an array of references to XMLBranches within the specified path, tag name, attribute name, and attribute value
129
	  *	@method		getBranches
130
	  *	@param		optional string tagPath
131
	  *	@param		optional string tagName
132
	  *	@param		optional string attrName
133
	  *	@param		optional string attrValue
134
	  *	@returns	array of references to XMLBranch objects that meet specified criteria, or false if none found
135
	  */
136
	function getBranches($tagPath = "", $tagName = "", $attrName = "", $attrValue = "") {
137
		$branchArray = array();
138
		if($tagPath == "")
139
			$tagPath = $this->tag->getTagName();
140
		$tags = explode($this->pathSeparator, $tagPath);
141
		if($this->tag->getTagName() == $tags[0]) {
142
			if(count($tags) == 1) {
143
				$arrKeys = array_keys($this->nodes);
144
				for($index = 0; $index < count($arrKeys); $index ++) {
145
					if(gettype($this->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($this->nodes[$arrKeys[$index]])) == "xmlbranch") {
146
						if(($tagName == "" || $this->nodes[$arrKeys[$index]]->tag->getTagName() == $tagName) &&
147
							($attrName == "" || $this->nodes[$arrKeys[$index]]->tag->attributeExists($attrName)) &&
148
							($attrValue == "" || $this->nodes[$arrKeys[$index]]->tag->getTagAttribute($attrName) == $attrValue)) {
149
							$branchArray[] = &$this->nodes[$arrKeys[$index]];
150
						}
151
					}
152
				}
153
			}
154
			else {
155
				$arrKeys = array_keys($this->nodes);
156
				for($index = 0; $index < count($arrKeys); $index ++) {
157
					if(gettype($this->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($this->nodes[$arrKeys[$index]])) == "xmlbranch") {
158
						if($this->nodes[$arrKeys[$index]]->tag->getTagName() == $tags[1]) {
159
							$newTagPath = implode($this->pathSeparator, array_slice($tags, 1));
160
							$newArray = $this->nodes[$arrKeys[$index]]->getBranches($newTagPath, $tagName, $attrName, $attrValue);
161
							if($newArray !== false)
162
								$branchArray = array_merge($branchArray, $newArray);
163
						}
164
					}
165
				}
166
			}
167
		}
168
		if(count($branchArray) == 0)
169
			$branchArray = false;
170
		return $branchArray;
171
	}
172
 
173
	/**
174
	  *	Retrieves an array of references to XMLLeaf(s) within the specified path
175
	  *	@method		getLeafs
176
	  *	@param		optional string tagPath
177
	  *	@returns	array of references to XMLLeaf objects in specified tag path, false if none found
178
	  */
179
	function getLeafs($tagPath = "") {
180
		$leafArray = array();
181
		if($tagPath == "")
182
			$tagPath = $this->tag->getTagName();
183
		$tags = explode($this->pathSeparator, $tagPath);
184
		if($this->tag->getTagName() == $tags[0]) {
185
			if(count($tags) == 1) {
186
				$arrKeys = array_keys($this->nodes);
187
				for($index = 0; $index < count($arrKeys); $index ++) {
188
					if(gettype($this->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($this->nodes[$arrKeys[$index]])) == "xmlleaf") {
189
						$leafArray[] = &$this->nodes[$arrKeys[$index]];
190
					}
191
				}
192
			}
193
			else {
194
				$arrKeys = array_keys($this->nodes);
195
				for($index = 0; $index < count($arrKeys); $index ++) {
196
					if(gettype($this->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($this->nodes[$arrKeys[$index]])) == "xmlbranch") {
197
						if($this->nodes[$arrKeys[$index]]->tag->getTagName() == $tags[1]) {
198
							$newTagPath = implode($this->pathSeparator, array_slice($tags, 1));
199
							$newArray = $this->nodes[$arrKeys[$index]]->getLeafs($newTagPath);
200
							if($newArray !== false)
201
								$leafArray = array_merge($leafArray, $newArray);
202
						}
203
					}
204
				}
205
			}
206
		}
207
		if(count($leafArray) == 0)
208
			$leafArray = false;
209
		return $leafArray;
210
	}
211
 
212
	/**
213
	  *	Returns attribute value of the specified tag and tagpath
214
	  *	@method		getTagAttribute
215
	  *	@param		string attributeName
216
	  *	@param		optional string tagPath
217
	  *	@returns	attribute of the specified tag if successful, false otherwise
218
	  */
219
	function getTagAttribute($attributeName, $tagPath = "") {
220
		if($tagPath == "")
221
			$tagPath = $this->tag->getTagName();
222
		$tags = explode($this->pathSeparator, $tagPath);
223
		$attributeValue = false;
224
		if($this->tag->getTagName() == $tags[0]) {
225
			if(sizeof($tags) == 1) {
226
				if($this->tag->attributeExists($attributeName))
227
					$attributeValue = $this->tag->getTagAttribute($attributeName);
228
			}
229
			else {
230
				foreach($this->nodes as $node) {
231
					if(strtolower(get_class($node)) == "xmlbranch")
232
						if($node->tag->getTagName() == $tags[1]) {
233
							$newTagPath = implode($this->pathSeparator, array_slice($tags, 1));
234
							$attributeValue = $node->getTagAttribute($attributeName, $newTagPath);
235
						}
236
				}
237
			}
238
		}
239
		return $attributeValue;
240
	}
241
 
242
	/**
243
	  *	Returns contents of the specified tag path
244
	  *	@method		getTagContent
245
	  *	@param		optional string tagPath
246
	  *	@returns	content of the tag from the specified path if successful, false otherwise
247
	  */
248
	function getTagContent($tagPath = "") {
249
		if($tagPath == "")
250
			$tagPath = $this->tag->getTagName();
251
		$tags = explode($this->pathSeparator, $tagPath);
252
		$tagValue = false;
253
		if($this->tag->getTagName() == $tags[0]) {
254
			if(sizeof($tags) == 1)
255
				$tagValue = $this->getXMLContent();
256
			else {
257
				foreach($this->nodes as $node) {
258
					if(strtolower(get_class($node)) == "xmlbranch")
259
						if($node->tag->getTagName() == $tags[1]) {
260
							$newTagPath = implode($this->pathSeparator, array_slice($tags, 1));
261
							$tagValue = $node->getTagContent($newTagPath);
262
						}
263
				}
264
			}
265
		}
266
		return $tagValue;
267
	}
268
 
269
	/**
270
	  *	Retrieves the tag name of the current object
271
	  *	@method		getTagName
272
	  *	@returns	tag name
273
	  */
274
	function getTagName() {
275
		return($this->tag->getTagName());
276
	}
277
 
278
	/**
279
	  *	Gets contents from the current object
280
	  *	@method		getXMLContent
281
	  *	@returns	contents of the current XML tag
282
	  */
283
	function getXMLContent() {
284
		$xmlContent = "";
285
		foreach($this->nodes as $node) {
286
			if(gettype($node) == "object") {
287
				if(strtolower(get_class($node)) == "xmlbranch")
288
					$xmlContent .= $node->getXMLString();
289
				elseif(strtolower(get_class($node)) == "xmlleaf")
290
					$xmlContent .= $node->getValue();
291
			}
292
		}
293
		return $xmlContent;
294
	}
295
 
296
	/**
297
	  *	Gets the whole XML string of the current object
298
	  *	@method		getXMLString
299
	  *	@param		optional mixed indent
300
	  *	@returns	complete XML string of current object
301
	  */
302
	function getXMLString($indent = false) {
303
		$xmlString = "";
304
		$containsBranches = false;
305
		$containsLeafs = false;
306
		$newIndent = false;
307
		if($indent === false)
308
			$newIndent = false;
309
		else {
310
			$newIndent = $indent + 1;
311
			$this->tag->setTagFormat($this->tag->FORMAT_INDENT, $indent);
312
		}
313
		foreach($this->nodes as $node) {
314
			if(gettype($node) == "object") {
315
				if(strtolower(get_class($node)) == "xmlbranch") {
316
					$this->tag->tagContent .= $node->getXMLString($newIndent);
317
					$containsBranches = true;
318
				}
319
				elseif(strtolower(get_class($node)) == "xmlleaf") {
320
					$this->tag->tagContent .= $node->getValue();
321
					$containsLeafs = true;
322
				}
323
			}
324
		}
325
		if($containsBranches)
326
			$this->tag->setTagFormatEndTag(true);
327
		$xmlString = $this->tag->getTagString();
328
		$this->tag->setTagContent("");
329
		return $xmlString;
330
	}
331
 
332
	/**
333
	  *	Find out whether the current object has any branches
334
	  *	@method		hasBranch
335
	  *	@returns	true if branches exist, false otherwise
336
	  */
337
	function hasBranch() {
338
		$hasBranch = false;
339
		foreach($this->nodes as $node) {
340
			if(strtolower(get_class($node)) == "xmlbranch") {
341
				$hasBranch = true;
342
				break;
343
			}
344
		}
345
		return $hasBranch;
346
	}
347
 
348
	/**
349
	  *	Find out whether the current object has any leaf(s)
350
	  *	@method		hasLeaf
351
	  *	@returns	true if leaf(s) exist, false otherwise
352
	  */
353
	function hasLeaf() {
354
		$hasLeaf = false;
355
		foreach($this->nodes as $node) {
356
			if(strtolower(get_class($node)) == "xmlleaf") {
357
				$hasLeaf = true;
358
				break;
359
			}
360
		}
361
		return $hasLeaf;
362
	}
363
 
364
	/**
365
	  *	Parse entire XML string into the current object; also called from constructor
366
	  *	@method		parseFromString
367
	  *	@param		string parseString
368
	  *	@returns	none
369
	  */
370
	function parseFromString($parseString) {
371
		$tagResult = $this->tag->setTagFromString($parseString);
372
		if($tagResult !== false) {
373
			$this->parseNodesFromTag();
374
			$this->tag->setTagContent("");
375
		}
376
	}
377
 
378
	/**
379
	  *	Parses the current tag content into Branches and Leaf(s); called from parseFromString
380
	  *	@method		parseNodesFromTag
381
	  *	@returns	none
382
	  */
383
	function parseNodesFromTag() {
384
		$tempTag = new Tag();
385
		$parseString = $this->tag->getTagContent();
386
		while($tagParsed = $tempTag->setTagFromString($parseString)) {
387
			if($tagParsed[0] != 0 && substr($parseString, 0, $tagParsed[0]) != "")
388
				$this->addXMLLeaf(new XMLLeaf(substr($parseString, 0, $tagParsed[0])));
389
			$branch = new XMLBranch();
390
			$tempTagCopy = new Tag();
391
			$tempTagCopy->setTagName($tempTag->getTagName());
392
			$tempTagCopy->tagAttributes = $tempTag->tagAttributes;
393
			$tempTagCopy->setTagContent($tempTag->getTagContent());
394
			$branch->setTag($tempTagCopy);
395
			$branch->parseNodesFromTag();
396
			$branch->tag->setTagContent("");
397
			$this->addXMLBranch($branch);
398
			$parseString = substr($parseString, $tagParsed[1]);
399
		}
400
		if(strlen($parseString) > 0 && $parseString != "")
401
			$this->addXMLLeaf(new XMLLeaf($parseString));
402
	}
403
 
404
	/**
405
	  *	Removes all Branches from current object
406
	  *	@method		removeAllBranches
407
	  */
408
	function removeAllBranches() {
409
		foreach($this->nodes as $key => $value) {
410
			if(strtolower(get_class($value)) == "xmlbranch")
411
				unset($this->nodes[$key]);
412
		}
413
	}
414
 
415
	/**
416
	  *	Removes all Leaf(s) from current object
417
	  *	@method		removeAllLeafs
418
	  */
419
	function removeAllLeafs() {
420
		foreach($this->nodes as $key => $value) {
421
			if(strtolower(get_class($value)) == "xmlleaf")
422
				unset($this->nodes[$key]);
423
		}
424
	}
425
 
426
	/**
427
	  *	Removes Branches with the specified criteria
428
	  *	@method		removeBranches
429
	  *	@param		optional string tagPath
430
	  *	@param		optional string tagName
431
	  *	@param		optional string attrName
432
	  *	@param		optional string attrValue
433
	  *	@returns	number of branches deleted
434
	  */
435
	function removeBranches($tagPath = "", $tagName = "", $attrName = "", $attrValue = "") {
436
		$branchesDeleted = 0;
437
		$referencedBranches = array();
438
		$tags = explode($this->pathSeparator, $tagPath);
439
		if(count($tags) > 1) {
440
			$parentTagName = array_pop($tags);
441
			$parentTagPath = implode($this->pathSeparator, $tags);
442
			$referencedBranches = $this->getBranches($parentTagPath, $parentTagName);
443
		}
444
		else {
445
			$referencedBranches[] = &$this;
446
		}
447
		for($i = 0; $i < count($referencedBranches); $i ++) {
448
			$arrKeys = array_keys($referencedBranches[$i]->nodes);
449
			for($index = 0; $index < count($arrKeys); $index ++) {
450
				if(gettype($referencedBranches[$i]->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($referencedBranches[$i]->nodes[$arrKeys[$index]])) == "xmlbranch") {
451
					if(($tagName == "" || $referencedBranches[$i]->nodes[$arrKeys[$index]]->tag->getTagName() == $tagName) &&
452
						($attrName == "" || $referencedBranches[$i]->nodes[$arrKeys[$index]]->tag->attributeExists($attrName)) &&
453
						($attrValue == "" || $referencedBranches[$i]->nodes[$arrKeys[$index]]->tag->getTagAttribute($attrName) == $attrValue)) {
454
						$referencedBranches[$i]->removeNode($arrKeys[$index]);
455
						$branchesDeleted ++;
456
					}
457
				}
458
			}
459
		}
460
		return $branchesDeleted;
461
	}
462
 
463
	/**
464
	  *	Sets tag object of a branch specified by branch ID for the current object; see getBranches and setTag
465
	  *	@method		setBranchTag
466
	  *	@param		mixed branchId
467
	  *	@param		object tag
468
	  *	@returns	true on success, false otherwise
469
	  */
470
	function setBranchTag($branchId, $tag) {
471
		$success = true;
472
		if(strtolower(get_class($this->nodes[$branchId])) == "xmlbranch" && strtolower(get_class($tag)) == "tag")
473
			$this->nodes[$branchId]->setTag($tag);
474
		else
475
			$success = false;
476
		return $success;
477
	}
478
 
479
	/**
480
	  *	Sets tag object of the current object
481
	  *	@method		setTag
482
	  *	@param		object tag
483
	  *	@returns	true if successful, false otherwise
484
	  */
485
	function setTag($tag) {
486
		$success = true;
487
		if(strtolower(get_class($tag)) == "tag")
488
			$this->tag = $tag;
489
		else
490
			$success = false;
491
		return $success;
492
	}
493
 
494
	/**
495
	  *	Sets an attribute name and value on an existing tag found via tagpath string
496
	  *	@method		setTagAttribute
497
	  *	@param		string attributeName
498
	  *	@param		optional string attributeValue
499
	  *	@param		optional string tagPath
500
	  *	@returns	true if successful, false otherwise
501
	  */
502
	function setTagAttribute($attributeName, $attributeValue = "", $tagPath = "") {
503
		if($tagPath == "")
504
			$tagPath = $this->tag->getTagName();
505
		$success = true;
506
		$tags = explode($this->pathSeparator, $tagPath);
507
		if($this->tag->getTagName() == $tags[0]) {
508
			if(sizeof($tags) == 1)
509
				$this->tag->setAttribute($attributeName, $attributeValue);
510
			else {
511
				$nodeTagFound = false;
512
				reset($this->nodes);
513
				$arrKeys = array_keys($this->nodes);
514
				for($index = 0; $index < count($arrKeys); $index ++) {
515
					$node =& $this->nodes[$arrKeys[$index]];
516
					if(strtolower(get_class($node)) == "xmlbranch")
517
						if($node->tag->getTagName() == $tags[1]) {
518
							$newTagPath = implode($this->pathSeparator, array_slice($tags, 1));
519
							$success = $node->setTagAttribute($attributeName, $attributeValue, $newTagPath);
520
							$nodeTagFound = true;
521
						}
522
				}
523
				if(!$nodeTagFound)
524
					$success = false;
525
			}
526
		}
527
		else
528
			$success = false;
529
		return $success;
530
	}
531
 
532
	/**
533
	  *	Sets content of the specified tag
534
	  *	@method		setTagContent
535
	  *	@param		mixed content
536
	  *	@param		optional string tagPath
537
	  *	@returns	true if successful, false otherwise
538
	  */
539
	function setTagContent($content, $tagPath = "") {
540
		if($tagPath == "")
541
			$tagPath = $this->tag->getTagName();
542
		$success = true;
543
		$tags = explode($this->pathSeparator, $tagPath);
544
		if($this->tag->getTagName() == $tags[0]) {
545
			if(sizeof($tags) == 1) {
546
				//$this->nodes = array(new XMLLeaf($content));
547
				$this->removeAllNodes();
548
				$this->addXMLLeaf(new XMLLeaf($content));
549
			}
550
			else {
551
				$nodeTagFound = false;
552
				reset($this->nodes);
553
				$arrKeys = array_keys($this->nodes);
554
				for($index = 0; $index < count($arrKeys); $index ++) {
555
					$node =& $this->nodes[$arrKeys[$index]];
556
					if(strtolower(get_class($node)) == "xmlbranch")
557
						if($node->tag->getTagName() == $tags[1]) {
558
							$newTagPath = implode($this->pathSeparator, array_slice($tags, 1));
559
							$success = $node->setTagContent($content, $newTagPath);
560
							$nodeTagFound = true;
561
						}
562
				}
563
				if(!$nodeTagFound) {
564
					$branch = new XMLBranch();
565
					$branch->setTag(new Tag($tags[1]));
566
					$newTagPath = implode($this->pathSeparator, array_slice($tags, 1));
567
					$branch->setTagContent($content, $newTagPath);
568
					$this->addXMLBranch($branch);
569
				}
570
			}
571
		}
572
		return $success;
573
	}
574
 
575
}
576
 
577
import("org.active-link.xml.XMLBranch");
578
import("org.active-link.xml.XMLLeaf");
579
 
580
?>