Jump to content
php.lv forumi

xml to string


keiG
 Share

Recommended Posts

Ir nepieciešams no DNB bankas "konta pārskats" xml failu pārkonvertēt csv formātā.

Atradu šādu skriptu, kas konvertē xml uz csv, bet man nekādi nesanāca to pārveidot, lai visu dabūtu stringā, jo klasēs un objektus vēl nav sanācis laika apgūt.

 

<?php
class path
{
   public $colid;
   public $parent;
   public $name;
   public $children;
   public $branch;
   public $counters;
   public $hastext;
   public $rows;
   public $row; //current row to set values

   function __construct($parent, $name) {
    $this->colid = null;
    $this->branch = false;
    $this->hastext = false;
    $this->counter = 0;
    $this->rows = array();
    $this->row = array();
    $this->parent = $parent;
    $this->name = $name;
    //register myself to parent
    $this->children = array();
    if($parent !== null) {
	    $parent->children[] = $this;
    }
   }
   function getFullPath()
   {
    $fullname = "";
    if($this->parent !== null) {
	    $fullname .= $this->parent->getFullPath()."/";
    }
    $fullname .= $this->name;
    return $fullname;
   }
   function findChild($name) {
    foreach($this->children as $child) {
	    if($child->name == $name) return $child;
    }
    return null;
   }
   function analyzeColumn(&$cols, $under_branch = false) {
    if($under_branch && $this->hastext) {
	    $this->colid = sizeof($cols);
	    $cols[] = $this;
    }
    foreach($this->children as $child) {
	    if($this->branch) {
		    $under_branch = true;
	    }
	    $child->analyzeColumn($cols, $under_branch);
    }
   }
   function analyzeBranch() {
    foreach($this->children as $child) {
	    if($child->counter > 1) {
		    $child->branch = true;
	    }
	    $child->counter = 0;
    }
   }
   function getBranch()
   {
    if($this->branch) return $this;
    if($this->parent !== null) {
	    return $this->parent->getBranch();
    }
    return null;
   }
   function getRoot()
   {
    if($this->parent === null) return $this;
    return $this->parent->getRoot();
   }
   function closeBranch()
   {
    //close this branch and send all records to parent branch (or root)
    $parent_branch = $this->parent->getBranch();
    if($parent_branch === null) {
	    $parent_branch = $this->getRoot();
    }
    //merge my row and sub-rows to parent rows.
    if(sizeof($this->rows) == 0) {
	    $parent_branch->rows[] = merge_row($parent_branch->row, $this->row);
    } else {
	    foreach($this->rows as $row) {
		    $parent_branch->rows[] = merge_row($parent_branch->row, merge_row($this->row, $row));
	    }
    }
    //reset this and child rows
    $this->row = array();
    $this->rows = array();
   }
   function output($colnum)    {

    foreach($this->rows as $row) {
	    for($i = 0;$i < $colnum;$i++) {
		    if(isset($row[$i])) {
			    $value = "\"".str_replace("\"", "\\\"", $row[$i])."\"";
			    echo $value;
		    }
		    echo ",";
	    }
	    echo "<br/>\n";
    }
   }
}
function merge_row($row1, $row2)
{
   foreach($row2 as $key=>$col) {
    $row1[$key] = $col;
   }
   return $row1;
}
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));
}
?>

 

output un xml2csv funkcijas taisa echo, bet tur drošvien vajadzētu $string+=... , bet nesaprotu, kā no šī izvilkt stringu! Ir kādi varianti? Vai arī, kādi ieteiktumi, lai pats varu tikt galā, ja nevēlaties uz paplātes atnest? Varbūt pat kāds īsāks skripts ir aizķēries?

Link to comment
Share on other sites

Kā jau briedis teica, izmanto SimpleXML un sadrukā parastā tabulas veidā rezultātus un uzliec header CSV.

 

header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");

echo "xml11, xml12, xml13" . "\n\r";
echo "xml21, xml22, xml23" . "\n\r";
echo "xml31, xml32, xml33" . "\n\r";

...

 

Lieta darīta.

Link to comment
Share on other sites

Mana atrastā funkcija pilda vajadzīgo darbu, bet tā izmet visu ar echo, ko man nevajag Nepieciešama ir tikai CSV struktūra iekš stringa, kurš pēc tam iet uz db.

Vienkārši visām pārējām bankām nolasa csv un pēc +/- viena algoritma iet uz db.

Man vienkārši savu pārzotāju nav īsti laika veidot, bet nu laikam jau būs vien jātaisa.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...