function xml2csv($xml_content) { $xml = new XMLReader(); $xml->XML($xml_content); //First pass - discover all path and branch points $cols = array(); $root = new path(null, "root"); $current = $root; while ($xml->read()) { if (in_array($xml->nodeType, array(XMLReader::TEXT, XMLReader::CDATA, XMLReader::WHITESPACE, XMLReader::SIGNIFICANT_WHITESPACE))) { if (trim($xml->value) == "") { continue; } $current->hastext = true; } if ($xml->nodeType == XMLReader::ELEMENT) { $child = $current->findChild($xml->name); if ($child !== null) { $current = $child; $current->counter++; } else { //brand new path $current = new path($current, $xml->name); } } if ($xml->nodeType == XMLReader::END_ELEMENT) { $current->analyzeBranch(); $current = $current->parent; } } //output column headder $cols = array(); $root->analyzeColumn($cols); foreach ($cols as $path) { //append parent's path name to be more descriptive if ($path->parent !== null) { echo $path->parent->name . "/"; } echo $path->name; echo ","; } echo "\n"; //Second pass - map values to current branch points $xml->XML($xml_content); $current = $root; $branch = null; while ($xml->read()) { if (in_array($xml->nodeType, array(XMLReader::TEXT, XMLReader::CDATA, XMLReader::WHITESPACE, XMLReader::SIGNIFICANT_WHITESPACE))) { $value = trim($xml->value); if (trim($xml->value) == "") { continue; } $branch->row[$current->colid] = $value; } if ($xml->nodeType == XMLReader::ELEMENT) { $current = $current->findChild($xml->name); $branch = $current->getBranch(); } if ($xml->nodeType == XMLReader::END_ELEMENT) { if ($current == $branch) { $branch->closeBranch(); } $current = $current->parent; $branch_new = $current->getBranch(); if ($branch_new !== null) { $branch = $branch_new; } } } //dump the content $root->output(sizeof($cols)); }