示例#1
0
 /**
 	  ARRAY TO XML:  Usage example.
 	  v1 - 05/May/2008
 	 $a = array(
 		'title' => array(
 			'value'   => 'this is a section element with an id = title',
 			'tagname' => 'section' // the element will be <section id="title">this is a ...</section>
 		),
 		// same as above
 		'section' => array(
 			'value'	=> 'this is a section element with an id = title2',
 			'id'    => 'title2'
 		),
 		'metatags' => array(
 			'tagname' => 'section',
 			// if you want to declare several elements with the same tag use numbers
 			'meta'    => array(
 				0 => array(
 					'http-equiv' => 'content-language',
 					'content'    => 'es-mx',
 					'id'         => 'numbered'
 				),
 				1 => array(
 					'name'    => 'description',
 					// this will be added as attribute and all the html characters will be converted
 					'content' => 'Giro Diseño - Su mejor <a>opción</a> en el desarrollo web'
 				),
 				2 => array(
 					'value'  => 'text value',
 					'tagname' => 'othermeta' // this method of giving an id won't work and will be ignored
 				),
 				'a' => 'foo'  // this is invalid it will be removed
 			)
 		),
 		'content' => array(
 			'tagname' => 'section',
 			'value'   => '<h1>Ñ</h1><p>Hola Mundo! ñoño!</p>' // this will use CDATA
 		),
 		'tagname' => 'foo',		// this is invalid. it will be ignored
 		'value' => 'hola mundo' // this is invalid. it will be ignored
 	);
 	**/
 private static function _array2XML($array, $obj = false, $valid = false)
 {
     // if we want to enable formatoutput, we must generate valid XML.
     // so, we must prevent the creation of textcontent elements in the
     // same level as element nodes. ej: <element><otherelement />text content</element>
     // for this, we must prevent the array to have mixed values,
     // so, we check for arrays within arrays (element nodes) and if found something
     // remove all non array values (textcontent elements).
     // of course this could be expensive if we're dealing with large arrays
     // so this is disabled by default and it's only enabled if formatoutput is set to true
     if ($valid) {
         if (Arrays::value_has_type('array', $array)) {
             if ($naa = Arrays::value_get_type('!array', $array)) {
                 foreach ($naa as $k => $v) {
                     unset($array[$k]);
                 }
             }
         }
     }
     // start the normal inspection of the array
     foreach ($array as $key => $val) {
         $key = strtolower($key);
         // if value isn't array it means that this is a value or an attribute
         if (!is_array($val)) {
             $val = utf8_encode($val);
             // determine if the value must be enclosed with cdata;
             $cdata = false;
             if (htmlspecialchars($val) != $val) {
                 $cdata = true;
             }
             // if a tagname key is defined ignore it
             if ($key == 'tagname') {
                 continue;
             }
             // set the value if any
             if ($key == 'value') {
                 // if the value has specialchars use cdata instead of textnode
                 if ($cdata) {
                     $o = self::$_DOM->createCDATASection($val);
                 } else {
                     $o = self::$_DOM->createTextNode($val);
                 }
                 $obj->appendChild($o);
             } else {
                 $obj->setAttribute($key, $cdata ? htmlspecialchars($val) : $val);
             }
             // skip to the next key;
             continue;
         }
         // value is an array
         $tag = $key;
         $id = null;
         // if a tagname key exists, set it's value as an element name.
         // and store the key name as an id attribute, also, we uset the
         // tagname key so it doesn't interfere later.
         if (array_key_exists('tagname', $val)) {
             $tag = $val['tagname'];
             $id = $key;
             unset($val['tagname']);
         }
         // if current array has numbered arrays, it means that
         // we're dealing with the creation of several elements with
         // the same tagname. to deal with this we force an extra foreach loop.
         if (Arrays::key_has_type('int', $val)) {
             // unset any array value which its key variable type isn't a integer
             if ($nan = Arrays::key_get_type('!int', $val)) {
                 foreach ($nan as $k => $v) {
                     unset($val[$k]);
                 }
             }
             // we make sure the foreach loop runs at least once.
         } else {
             $val = array($val);
         }
         foreach ($val as $e) {
             $node = self::$_DOM->createElement($tag);
             if ($id) {
                 $node->setAttribute('id', $id);
             }
             self::_array2XML($e, $node, $valid);
             $obj->appendChild($node);
         }
     }
     return $obj;
 }