Tree(); $this->pathSeparator = "/"; $this->tag = new Tag(); if(is_string($argument)) { // if this is an XML string to be parsed if(strpos($argument, $this->tag->tagEndOpen) > 0 || strpos($argument, $this->tag->tagClose) > 0) $this->parseFromString($argument); // else if this is a tag path to be created elseif(strpos($argument, $this->pathSeparator) > 0) { $tags = explode($this->pathSeparator, $argument); $this->tag->setTagName($tags[0]); $this->setTagContent("", $argument); } else $this->tag->setTagName($argument); $success = true; } else $success = false; return $success; } /** * Adds another XML tree as a branch to the current XML object * @method addXMLAsBranch * @param object xml * @param optional mixed id * @returns true if successful, false otherwise */ function addXMLAsBranch($xml, $id = -1) { $success = false; if(is_object($xml) && strtolower(get_class($xml)) == "xml") { $newBranch = new XMLBranch(); $newBranch->nodes = $xml->nodes; $newBranch->tag = $xml->tag; $success = $this->addXMLBranch($newBranch, $id); } return $success; } /** * Adds XML Branch to the current XML object * @method addXMLBranch * @param object xmlBranch * @param optional mixed id * @returns true if successful, false otherwise */ function addXMLBranch($xmlBranch, $id = -1) { $success = false; if(is_object($xmlBranch) && strtolower(get_class($xmlBranch)) == "xmlbranch") { $xmlBranch->setParentXML($this); $success = $this->addNode($id, $xmlBranch); } return $success; } /** * Adds XML Leaf to the current XML object * @method addXMLLeaf * @param object xmlLeaf * @param optional mixed id * @returns true if successful, false otherwise */ function addXMLLeaf($xmlLeaf, $id = -1) { $success = false; if(is_object($xmlLeaf) && strtolower(get_class($xmlLeaf)) == "xmlleaf") { $xmlLeaf->setParentXML($this); $success = $this->addNode($id, $xmlLeaf); } return $success; } /** * Retrieves an array of references to XMLBranches within the specified path, tag name, attribute name, and attribute value * @method getBranches * @param optional string tagPath * @param optional string tagName * @param optional string attrName * @param optional string attrValue * @returns array of references to XMLBranch objects that meet specified criteria, or false if none found */ function getBranches($tagPath = "", $tagName = "", $attrName = "", $attrValue = "") { $branchArray = array(); if($tagPath == "") $tagPath = $this->tag->getTagName(); $tags = explode($this->pathSeparator, $tagPath); if($this->tag->getTagName() == $tags[0]) { if(count($tags) == 1) { $arrKeys = array_keys($this->nodes); for($index = 0; $index < count($arrKeys); $index ++) { if(gettype($this->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($this->nodes[$arrKeys[$index]])) == "xmlbranch") { if(($tagName == "" || $this->nodes[$arrKeys[$index]]->tag->getTagName() == $tagName) && ($attrName == "" || $this->nodes[$arrKeys[$index]]->tag->attributeExists($attrName)) && ($attrValue == "" || $this->nodes[$arrKeys[$index]]->tag->getTagAttribute($attrName) == $attrValue)) { $branchArray[] = &$this->nodes[$arrKeys[$index]]; } } } } else { $arrKeys = array_keys($this->nodes); for($index = 0; $index < count($arrKeys); $index ++) { if(gettype($this->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($this->nodes[$arrKeys[$index]])) == "xmlbranch") { if($this->nodes[$arrKeys[$index]]->tag->getTagName() == $tags[1]) { $newTagPath = implode($this->pathSeparator, array_slice($tags, 1)); $newArray = $this->nodes[$arrKeys[$index]]->getBranches($newTagPath, $tagName, $attrName, $attrValue); if($newArray !== false) $branchArray = array_merge($branchArray, $newArray); } } } } } if(count($branchArray) == 0) $branchArray = false; return $branchArray; } /** * Retrieves an array of references to XMLLeaf(s) within the specified path * @method getLeafs * @param optional string tagPath * @returns array of references to XMLLeaf objects in specified tag path, false if none found */ function getLeafs($tagPath = "") { $leafArray = array(); if($tagPath == "") $tagPath = $this->tag->getTagName(); $tags = explode($this->pathSeparator, $tagPath); if($this->tag->getTagName() == $tags[0]) { if(count($tags) == 1) { $arrKeys = array_keys($this->nodes); for($index = 0; $index < count($arrKeys); $index ++) { if(gettype($this->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($this->nodes[$arrKeys[$index]])) == "xmlleaf") { $leafArray[] = &$this->nodes[$arrKeys[$index]]; } } } else { $arrKeys = array_keys($this->nodes); for($index = 0; $index < count($arrKeys); $index ++) { if(gettype($this->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($this->nodes[$arrKeys[$index]])) == "xmlbranch") { if($this->nodes[$arrKeys[$index]]->tag->getTagName() == $tags[1]) { $newTagPath = implode($this->pathSeparator, array_slice($tags, 1)); $newArray = $this->nodes[$arrKeys[$index]]->getLeafs($newTagPath); if($newArray !== false) $leafArray = array_merge($leafArray, $newArray); } } } } } if(count($leafArray) == 0) $leafArray = false; return $leafArray; } /** * Returns attribute value of the specified tag and tagpath * @method getTagAttribute * @param string attributeName * @param optional string tagPath * @returns attribute of the specified tag if successful, false otherwise */ function getTagAttribute($attributeName, $tagPath = "") { if($tagPath == "") $tagPath = $this->tag->getTagName(); $tags = explode($this->pathSeparator, $tagPath); $attributeValue = false; if($this->tag->getTagName() == $tags[0]) { if(sizeof($tags) == 1) { if($this->tag->attributeExists($attributeName)) $attributeValue = $this->tag->getTagAttribute($attributeName); } else { foreach($this->nodes as $node) { if(strtolower(get_class($node)) == "xmlbranch") if($node->tag->getTagName() == $tags[1]) { $newTagPath = implode($this->pathSeparator, array_slice($tags, 1)); $attributeValue = $node->getTagAttribute($attributeName, $newTagPath); } } } } return $attributeValue; } /** * Returns contents of the specified tag path * @method getTagContent * @param optional string tagPath * @returns content of the tag from the specified path if successful, false otherwise */ function getTagContent($tagPath = "") { if($tagPath == "") $tagPath = $this->tag->getTagName(); $tags = explode($this->pathSeparator, $tagPath); $tagValue = false; if($this->tag->getTagName() == $tags[0]) { if(sizeof($tags) == 1) $tagValue = $this->getXMLContent(); else { foreach($this->nodes as $node) { if(strtolower(get_class($node)) == "xmlbranch") if($node->tag->getTagName() == $tags[1]) { $newTagPath = implode($this->pathSeparator, array_slice($tags, 1)); $tagValue = $node->getTagContent($newTagPath); } } } } return $tagValue; } /** * Retrieves the tag name of the current object * @method getTagName * @returns tag name */ function getTagName() { return($this->tag->getTagName()); } /** * Gets contents from the current object * @method getXMLContent * @returns contents of the current XML tag */ function getXMLContent() { $xmlContent = ""; foreach($this->nodes as $node) { if(gettype($node) == "object") { if(strtolower(get_class($node)) == "xmlbranch") $xmlContent .= $node->getXMLString(); elseif(strtolower(get_class($node)) == "xmlleaf") $xmlContent .= $node->getValue(); } } return $xmlContent; } /** * Gets the whole XML string of the current object * @method getXMLString * @param optional mixed indent * @returns complete XML string of current object */ function getXMLString($indent = false) { $xmlString = ""; $containsBranches = false; $containsLeafs = false; $newIndent = false; if($indent === false) $newIndent = false; else { $newIndent = $indent + 1; $this->tag->setTagFormat($this->tag->FORMAT_INDENT, $indent); } foreach($this->nodes as $node) { if(gettype($node) == "object") { if(strtolower(get_class($node)) == "xmlbranch") { $this->tag->tagContent .= $node->getXMLString($newIndent); $containsBranches = true; } elseif(strtolower(get_class($node)) == "xmlleaf") { $this->tag->tagContent .= $node->getValue(); $containsLeafs = true; } } } if($containsBranches) $this->tag->setTagFormatEndTag(true); $xmlString = $this->tag->getTagString(); $this->tag->setTagContent(""); return $xmlString; } /** * Find out whether the current object has any branches * @method hasBranch * @returns true if branches exist, false otherwise */ function hasBranch() { $hasBranch = false; foreach($this->nodes as $node) { if(strtolower(get_class($node)) == "xmlbranch") { $hasBranch = true; break; } } return $hasBranch; } /** * Find out whether the current object has any leaf(s) * @method hasLeaf * @returns true if leaf(s) exist, false otherwise */ function hasLeaf() { $hasLeaf = false; foreach($this->nodes as $node) { if(strtolower(get_class($node)) == "xmlleaf") { $hasLeaf = true; break; } } return $hasLeaf; } /** * Parse entire XML string into the current object; also called from constructor * @method parseFromString * @param string parseString * @returns none */ function parseFromString($parseString) { $tagResult = $this->tag->setTagFromString($parseString); if($tagResult !== false) { $this->parseNodesFromTag(); $this->tag->setTagContent(""); } } /** * Parses the current tag content into Branches and Leaf(s); called from parseFromString * @method parseNodesFromTag * @returns none */ function parseNodesFromTag() { $tempTag = new Tag(); $parseString = $this->tag->getTagContent(); while($tagParsed = $tempTag->setTagFromString($parseString)) { if($tagParsed[0] != 0 && substr($parseString, 0, $tagParsed[0]) != "") $this->addXMLLeaf(new XMLLeaf(substr($parseString, 0, $tagParsed[0]))); $branch = new XMLBranch(); $tempTagCopy = new Tag(); $tempTagCopy->setTagName($tempTag->getTagName()); $tempTagCopy->tagAttributes = $tempTag->tagAttributes; $tempTagCopy->setTagContent($tempTag->getTagContent()); $branch->setTag($tempTagCopy); $branch->parseNodesFromTag(); $branch->tag->setTagContent(""); $this->addXMLBranch($branch); $parseString = substr($parseString, $tagParsed[1]); } if(strlen($parseString) > 0 && $parseString != "") $this->addXMLLeaf(new XMLLeaf($parseString)); } /** * Removes all Branches from current object * @method removeAllBranches */ function removeAllBranches() { foreach($this->nodes as $key => $value) { if(strtolower(get_class($value)) == "xmlbranch") unset($this->nodes[$key]); } } /** * Removes all Leaf(s) from current object * @method removeAllLeafs */ function removeAllLeafs() { foreach($this->nodes as $key => $value) { if(strtolower(get_class($value)) == "xmlleaf") unset($this->nodes[$key]); } } /** * Removes Branches with the specified criteria * @method removeBranches * @param optional string tagPath * @param optional string tagName * @param optional string attrName * @param optional string attrValue * @returns number of branches deleted */ function removeBranches($tagPath = "", $tagName = "", $attrName = "", $attrValue = "") { $branchesDeleted = 0; $referencedBranches = array(); $tags = explode($this->pathSeparator, $tagPath); if(count($tags) > 1) { $parentTagName = array_pop($tags); $parentTagPath = implode($this->pathSeparator, $tags); $referencedBranches = $this->getBranches($parentTagPath, $parentTagName); } else { $referencedBranches[] = &$this; } for($i = 0; $i < count($referencedBranches); $i ++) { $arrKeys = array_keys($referencedBranches[$i]->nodes); for($index = 0; $index < count($arrKeys); $index ++) { if(gettype($referencedBranches[$i]->nodes[$arrKeys[$index]]) == "object" && strtolower(get_class($referencedBranches[$i]->nodes[$arrKeys[$index]])) == "xmlbranch") { if(($tagName == "" || $referencedBranches[$i]->nodes[$arrKeys[$index]]->tag->getTagName() == $tagName) && ($attrName == "" || $referencedBranches[$i]->nodes[$arrKeys[$index]]->tag->attributeExists($attrName)) && ($attrValue == "" || $referencedBranches[$i]->nodes[$arrKeys[$index]]->tag->getTagAttribute($attrName) == $attrValue)) { $referencedBranches[$i]->removeNode($arrKeys[$index]); $branchesDeleted ++; } } } } return $branchesDeleted; } /** * Sets tag object of a branch specified by branch ID for the current object; see getBranches and setTag * @method setBranchTag * @param mixed branchId * @param object tag * @returns true on success, false otherwise */ function setBranchTag($branchId, $tag) { $success = true; if(strtolower(get_class($this->nodes[$branchId])) == "xmlbranch" && strtolower(get_class($tag)) == "tag") $this->nodes[$branchId]->setTag($tag); else $success = false; return $success; } /** * Sets tag object of the current object * @method setTag * @param object tag * @returns true if successful, false otherwise */ function setTag($tag) { $success = true; if(strtolower(get_class($tag)) == "tag") $this->tag = $tag; else $success = false; return $success; } /** * Sets an attribute name and value on an existing tag found via tagpath string * @method setTagAttribute * @param string attributeName * @param optional string attributeValue * @param optional string tagPath * @returns true if successful, false otherwise */ function setTagAttribute($attributeName, $attributeValue = "", $tagPath = "") { if($tagPath == "") $tagPath = $this->tag->getTagName(); $success = true; $tags = explode($this->pathSeparator, $tagPath); if($this->tag->getTagName() == $tags[0]) { if(sizeof($tags) == 1) $this->tag->setAttribute($attributeName, $attributeValue); else { $nodeTagFound = false; reset($this->nodes); $arrKeys = array_keys($this->nodes); for($index = 0; $index < count($arrKeys); $index ++) { $node =& $this->nodes[$arrKeys[$index]]; if(strtolower(get_class($node)) == "xmlbranch") if($node->tag->getTagName() == $tags[1]) { $newTagPath = implode($this->pathSeparator, array_slice($tags, 1)); $success = $node->setTagAttribute($attributeName, $attributeValue, $newTagPath); $nodeTagFound = true; } } if(!$nodeTagFound) $success = false; } } else $success = false; return $success; } /** * Sets content of the specified tag * @method setTagContent * @param mixed content * @param optional string tagPath * @returns true if successful, false otherwise */ function setTagContent($content, $tagPath = "") { if($tagPath == "") $tagPath = $this->tag->getTagName(); $success = true; $tags = explode($this->pathSeparator, $tagPath); if($this->tag->getTagName() == $tags[0]) { if(sizeof($tags) == 1) { //$this->nodes = array(new XMLLeaf($content)); $this->removeAllNodes(); $this->addXMLLeaf(new XMLLeaf($content)); } else { $nodeTagFound = false; reset($this->nodes); $arrKeys = array_keys($this->nodes); for($index = 0; $index < count($arrKeys); $index ++) { $node =& $this->nodes[$arrKeys[$index]]; if(strtolower(get_class($node)) == "xmlbranch") if($node->tag->getTagName() == $tags[1]) { $newTagPath = implode($this->pathSeparator, array_slice($tags, 1)); $success = $node->setTagContent($content, $newTagPath); $nodeTagFound = true; } } if(!$nodeTagFound) { $branch = new XMLBranch(); $branch->setTag(new Tag($tags[1])); $newTagPath = implode($this->pathSeparator, array_slice($tags, 1)); $branch->setTagContent($content, $newTagPath); $this->addXMLBranch($branch); } } } return $success; } } import("org.active-link.xml.XMLBranch"); import("org.active-link.xml.XMLLeaf"); ?>