From 1434676e0f5a213b6feda28b660faa92c5aad919 Mon Sep 17 00:00:00 2001 From: icewing Date: Mon, 14 Apr 2008 18:31:31 +0000 Subject: Marcus Povey * XML Import processor git-svn-id: https://code.elgg.org/elgg/trunk@445 36083f99-b078-4883-b0ff-0f9b5a30f544 --- engine/lib/export.php | 79 +++++++++++++++++++--------------------- engine/lib/xml.php | 99 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 101 insertions(+), 77 deletions(-) (limited to 'engine') diff --git a/engine/lib/export.php b/engine/lib/export.php index 4247ae348..e997a1c5a 100644 --- a/engine/lib/export.php +++ b/engine/lib/export.php @@ -323,6 +323,40 @@ return create_metadata($guid, "import_uuid", $uuid); } + + $IMPORTED_DATA = array(); + $IMPORTED_OBJECT_COUNTER = 0; + + /** + * This function processes an element, passing elements to the plugin stack to see if someone will + * process it. + * + * If nobody processes the top level element, the sub level elements are processed. + * + * @param array $element The dom tree. + */ + function __process_element($element) + { + global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER; + + // See if anyone handles this element, return true if it is. + $handled = trigger_plugin_hook("import", "all", array("name" => $element->name, "element" => $element), $to_be_serialised); + + // If not, then see if any of its sub elements are handled + if (!$handled) + { + if (isset($element->children)) + foreach ($element->children as $c) + __process_element($c); + } + else + { + $IMPORTED_OBJECT_COUNTER ++; // Increment validation counter + $IMPORTED_DATA[] = $handled; // Return the constructed object + } + + } + /** * Export a GUID. * @@ -361,42 +395,6 @@ return $output; } - - - - - - $IMPORTED_DATA = array(); - $IMPORTED_OBJECT_COUNTER = 0; - - /** - * This function processes an element, passing elements to the plugin stack to see if someone will - * process it. - * If nobody processes the top level element, the sub level elements are processed. - */ -/* function __process_element(array $dom) - { - global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER; - - foreach ($dom as $element) - { - // See if anyone handles this element, return true if it is. - $handled = trigger_plugin_hook("import", "all", array("name" => $element['name'], "element" => $element), $to_be_serialised); - - // If not, then see if any of its sub elements are handled - if (!$handled) - { - if (isset($element['elements'])) - __process_element($element['elements']); - } - else - { - $IMPORTED_OBJECT_COUNTER ++; // Increment validation counter - $IMPORTED_DATA[] = $handled; // Return the constructed object - } - } - } - /** * Import an XML serialisation of an object. * This will make a best attempt at importing a given xml doc. @@ -405,24 +403,19 @@ * @return array An array of imported objects (these have already been saved). * @throws Exception if there was a problem importing the data. */ -/* function import($xml) + function import($xml) { global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER; $IMPORTED_DATA = array(); $IMPORTED_OBJECT_COUNTER = 0; - $IMPORTED_GUID_MAP = array(); - $dom = __xml2array($xml); - - __process_element($dom); + __process_element(xml_2_object($xml)); if ($IMPORTED_OBJECT_COUNTER!= count($IMPORTED_DATA)) throw new ImportException("Not all elements were imported."); return $IMPORTED_DATA; } - - */ ?> \ No newline at end of file diff --git a/engine/lib/xml.php b/engine/lib/xml.php index 208763239..7b1c7da7b 100644 --- a/engine/lib/xml.php +++ b/engine/lib/xml.php @@ -11,6 +11,25 @@ * @link http://elgg.org/ */ + /** + * @class XMLElement + * A class representing an XML element for import. + */ + class XmlElement + { + /** The name of the element */ + public $name; + + /** The attributes */ + public $attributes; + + /** CData */ + public $content; + + /** Child elements */ + public $children; + }; + /** * This function serialises an object recursively into an XML representation. * The function attempts to call $data->export() which expects a stdClass in return, otherwise it will attempt to @@ -89,41 +108,53 @@ } /** - * XML 2 Array function. - * Taken from http://www.bytemycode.com/snippets/snippet/445/ - * @license UNKNOWN - Please contact if you are the original author of this code. - * @author UNKNOWN + * Parse an XML file into an object. + * Based on code from http://de.php.net/manual/en/function.xml-parse-into-struct.php by + * efredricksen at gmail dot com + * + * @param string $xml The XML. */ - function xml2array($xml) + function xml_2_object($xml) { - $xmlary = array(); - - $reels = '/<(\w+)\s*([^\/>]*)\s*(?:\/>|>(.*)<\/\s*\\1\s*>)/s'; - $reattrs = '/(\w+)=(?:"|\')([^"\']*)(:?"|\')/'; - - preg_match_all($reels, $xml, $elements); - - foreach ($elements[1] as $ie => $xx) { - $xmlary[$ie]["name"] = $elements[1][$ie]; - - if ($attributes = trim($elements[2][$ie])) { - preg_match_all($reattrs, $attributes, $att); - foreach ($att[1] as $ia => $xx) - $xmlary[$ie]["attributes"][$att[1][$ia]] = $att[2][$ia]; - } - - $cdend = strpos($elements[3][$ie], "<"); - if ($cdend > 0) { - $xmlary[$ie]["text"] = substr($elements[3][$ie], 0, $cdend - 1); - } - - if (preg_match($reels, $elements[3][$ie])) - $xmlary[$ie]["elements"] = __xml2array($elements[3][$ie]); - else if ($elements[3][$ie]) { - $xmlary[$ie]["text"] = $elements[3][$ie]; - } - } - - return $xmlary; + $parser = xml_parser_create(); + + // Parse $xml into a structure + xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + xml_parse_into_struct($parser, $xml, $tags); + + xml_parser_free($parser); + + $elements = array(); + $stack = array(); + + foreach ($tags as $tag) + { + $index = count($elements); + + if ($tag['type'] == "complete" || $tag['type'] == "open") + { + $elements[$index] = new XmlElement; + $elements[$index]->name = $tag['tag']; + $elements[$index]->attributes = $tag['attributes']; + $elements[$index]->content = $tag['value']; + + if ($tag['type'] == "open") + { + $elements[$index]->children = array(); + $stack[count($stack)] = &$elements; + $elements = &$elements[$index]->children; + } + } + + if ($tag['type'] == "close") + { + $elements = &$stack[count($stack) - 1]; + unset($stack[count($stack) - 1]); + } + } + + return $elements[0]; } + ?> \ No newline at end of file -- cgit v1.2.3