Last active
November 1, 2016 14:32
-
-
Save garagesocial/32334d9af04dfc0112fd to your computer and use it in GitHub Desktop.
Create etrepat/baum Header from XML Defined Hierarchy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Create headers from an xml string consisting of a hierarchy of nodes with attributes | |
* (ex: <header name="A"> <header name="AB" /> <header name="AC"> <header name="AD" /> </header> </header> | |
* | |
* @param string $content XML string containing hierarchy of nodes | |
* @return void | |
*/ | |
public function hfxParseContent($content) { | |
$xml = new SimpleXMLElement($content); | |
$nodeDictionaryHierarchy = array (); | |
$nodeDictionaryData = array(); | |
// parse and evaluate xml hierarchy | |
$this->hfxHierarchyParser($xml, $nodeDictionaryHierarchy, $nodeDictionaryData); | |
// process evaluated hierarchy and create headers | |
$this->hfxHeaderCreator($nodeDictionaryHierarchy, $nodeDictionaryData); | |
} | |
/** | |
* Parse XML and return hierarchy of immediate child. Each node in this hierarchy is represented by it's $uniqueKey | |
* (ex returned: array('A' => array('AB', 'AC'), 'AB' => array(), 'AC' => array('AD'), 'AD' =>array() ) | |
* | |
* @param SimpleXMLElement $node Starting node | |
* @param array &$nodeDictionaryHierarchy Array of node identifier with child header identifier | |
* array('A' => array('AB', 'AC'), ...) | |
* @param array &$nodeDictionaryData Array of each header with corresponding attributes | |
* array('A' => array('name' => 'A', 'slug' => 'a'), ...) | |
* @param string $nodeName XML node names | |
* @param string $uniqueKey Unique attribute to use to identify each node (internal) | |
* @return void | |
*/ | |
private static function hfxHierarchyParser($node, &$nodeDictionaryHierarchy, &$nodeDictionaryData, $nodeName = 'header', $uniqueKey = 'name') { | |
// each node needs initialization as an array to hold array of child nodes | |
if (array_key_exists("{$node[$uniqueKey]}", $nodeDictionaryHierarchy) === false) { | |
$nodeDictionaryHierarchy["{$node[$uniqueKey]}"] = array (); | |
$nodeDictionaryData["{$node[$uniqueKey]}"] = self::xml2array($node->attributes()); | |
} | |
// check if node has child nodes | |
$nodeNode = $node->$nodeName; | |
if (isset($nodeNode)) { | |
// push each immediate child to the current node array represented by it's $uniqueKey | |
for ($key = 0; ($key < $nodeNode->count()); $key++) { | |
$header = $nodeNode[$key]; | |
if (!in_array("{$node[$uniqueKey]}", $nodeDictionaryHierarchy["{$node[$uniqueKey]}"])) { | |
$nodeDictionaryHierarchy["{$node[$uniqueKey]}"][] = "{$header[$uniqueKey]}"; | |
} | |
// recurse through next level down | |
self::hfxHierarchyParser($header, $nodeDictionaryHierarchy, $nodeDictionaryData); | |
} | |
} | |
} | |
/** | |
* Create and link headers from the hierarchy array | |
* | |
* @param array $nodeDictionaryHierarchy | |
* @param array $nodeDictionaryData | |
* @return void | |
*/ | |
private static function hfxHeaderCreator(&$nodeDictionaryHierarchy, &$nodeDictionaryData) { | |
$headersPool = array(); | |
foreach ($nodeDictionaryHierarchy as $nodeKey => $childNodeKeys) { | |
// create header | |
if (!array_key_exists($nodeKey, $headersPool)) { | |
$nodeData = $nodeDictionaryData[$nodeKey]; | |
$headersPool[$nodeKey] = Header::create($nodeData); | |
} | |
// loop through each child of the header | |
foreach($childNodeKeys as $childNodeKey) { | |
// create child header | |
if (!array_key_exists($childNodeKey, $headersPool)) { | |
$childNodeData = $nodeDictionaryData[$childNodeKey]; | |
$headersPool[$childNodeKey] = Header::create($childNodeData); | |
} | |
// set as child | |
$headersPool[$childNodeKey]->makeChildOf($headersPool[$nodeKey]); | |
} | |
} | |
} | |
/** | |
* Convert SimpleXMLElement to array | |
* source: http://stackoverflow.com/questions/7778814/how-to-convert-simplexmlobject-into-php-array | |
* | |
* @param SimpleXMLElement $xml | |
* @return array | |
*/ | |
public function xml2array($xml) { | |
$arr = array(); | |
foreach ($xml as $element) { | |
$tag = $element->getName(); | |
$e = get_object_vars($element); | |
if (!empty($e)) { | |
$arr[$tag] = $element instanceof SimpleXMLElement ? xml2array($element) : $e; | |
} | |
else { | |
$arr[$tag] = trim($element); | |
} | |
} | |
return $arr; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
$data = ' | |
<header name="A" slug="a"> | |
<header name="B" slug="b"> | |
<header name="C" slug="c"> | |
<header name="D" slug="d" /> | |
</header> | |
</header> | |
</header> | |
'; | |
$this->hfxParseContent($data); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment