|
|
- <?php
-
- /*
- This file is part of ActiveLink PHP XML Package (www.active-link.com).
- Copyright (c) 2002-2004 by Zurab Davitiani
-
- You can contact the author of this software via E-mail at
- hattrick@mailcan.com
-
- ActiveLink PHP XML Package is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- ActiveLink PHP XML Package is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with ActiveLink PHP XML Package; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- import("org.active-link.xml.Tag");
- import("org.active-link.xml.Tree");
-
- /**
- * XML class provides a tree-like structure to read/write/modify XML
- * @class XML
- * @package org.active-link.xml
- * @author Zurab Davitiani
- * @version 0.4.0
- * @extends Tree
- * @requires Tag, Tree, XMLBranch, XMLLeaf
- * @see Tree
- */
-
- class XML extends Tree {
-
- // protected variables
- var $tag;
- var $pathSeparator;
-
- /**
- * If argument is an XML String it parses the string into XML object
- * If argument is a tag path, creates appropriate branches and tags
- * If argument is a simple string then sets that as a root tag name
- * @method XML
- * @param optional string argument
- * @returns none
- */
- function XML($argument = "") {
- $success = false;
- $this->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 && trim(substr($parseString, 0, $tagParsed[0]) != ""))
- $this->addXMLLeaf(new XMLLeaf(trim(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 = trim(substr($parseString, $tagParsed[1]));
- }
- if(strlen($parseString) > 0 && trim($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");
-
- ?>
|