PHP - XMLWriter将嵌套数组写入文件

时间:2014-08-03 13:53:45

标签: php file namespaces save xmlwriter

我跟随this example in XMLWiter functions,但我正在寻找一种方法将输出写入文件(sample.xml),我走过了很多线程,没有运气。 我知道解决方案可能很简单,但我只用了一个月就开始使用PHP。有人可以帮忙吗?

<?php

class XmlConstruct extends XMLWriter
{

/**
 * Constructor.
 * @param string $prm_rootElementName A root element's name of a current xml document
 * @param string $prm_xsltFilePath Path of a XSLT file.
 * @access public
 * @param null
 */
public function __construct($prm_rootElementName, $prm_xsltFilePath=''){
    $this->openMemory(); // change this with $this->openURI('your_file.xml');
    $this->setIndent(true);
    $this->setIndentString(' ');
    $this->startDocument('1.0', 'UTF-8');

    if($prm_xsltFilePath){
        $this->writePi('xml-stylesheet', 'type="text/xsl" href="'.$prm_xsltFilePath.'"');
    }

    $this->startElement($prm_rootElementName);
}

/**
 * Set an element with a text to a current xml document.
 * @access public
 * @param string $prm_elementName An element's name
 * @param string $prm_ElementText An element's text
 * @return null
 */
public function setElement($prm_elementName, $prm_ElementText){
    $this->startElement($prm_elementName);
    $this->text($prm_ElementText);
    $this->endElement();
}

/**
 * Construct elements and texts from an array.
 * The array should contain an attribute's name in index part
 * and a attribute's text in value part.
 * @access public
 * @param array $prm_array Contains attributes and texts
 * @return null
 */
public function fromArray($prm_array){
  if(is_array($prm_array)){
    foreach ($prm_array as $index => $element){
      if(is_array($element)){
        $this->startElement($index);
        $this->fromArray($element);
        $this->endElement();
      }
      else
        $this->setElement($index, $element);

    }
  }
}

/**
 * Return the content of a current xml document.
 * @access public
 * @param null
 * @return string Xml document
 */
public function getDocument(){     //comment this function
    $this->endElement();
    $this->endDocument();
    return $this->outputMemory();
}

/**
 * Output the content of a current xml document.
 * @access public
 * @param null
 */
public function output(){               //comment this function
    header('Content-type: text/xml');
    echo $this->getDocument();
}


}

//Example:

$contents = array(
  'page_title' => 'Generate a XHTML page from XML+XSLT files',
  'welcome_msg' => 'Simple XHTML document from XML+XSLT files!',
  'prova' => array(
    "gino" => array(
      "innergino" => "gino inner value"
     ),
   "filo" => "filodata"
),
);

$XmlConstruct = new XmlConstruct('root');
$XmlConstruct->fromArray($contents);
$XmlConstruct->output();              // comment this line

?>

1 个答案:

答案 0 :(得分:0)

最后,(在阅读了很多页面并尝试了很多例子之后),我按照自己的方式寻找解决方案。首先,as explained in this postXMLWriter是大xml文件的最佳选择(如我的情况),这就是为什么,经过深入研究,我没有遵循基于DOM的解决方案正如@Seyed Quarib所提出的那样,虽然阅读该主题非常有启发性。另一个问题是我的所有xml内容都需要包含在带有<p:TagName>这样的命名空间的标记中。我发现我需要使用XMLWriter::startElementNSXMLWriter::writeAttribute。正如我所说,我发现这样输出嵌套的xml标签非常方便我的目的(这是非常具体的)。这是代码,希望其他人能发现它有用:

<?php header('Content-Type: text/html; charset=utf-8') ?>
    <div class="save" style="width:100%; height:100px;">File saved</div>
    <?php

    class XmlConstruct extends XMLWriter
    {

    /**
    * Constructor.
    * @param string $prm_rootElementName A root element's name of a current xml document
    * @param string $prm_xsltFilePath Path of a XSLT file.
    * @access public
    * @param null
    */
    public function __construct($prm_rootElementName, $prm_xsltFilePath=''){
      $this->openURI('save-to-file.xml'); // changed
      $this->setIndent(true);
      $this->setIndentString(' ');
      $this->startDocument('1.0', 'UTF-8');

    if($prm_xsltFilePath){
      $this->writePi('xml-stylesheet', 'type="text/xsl" href="'.$prm_xsltFilePath.'"');
    }

      //$this->startElement($prm_rootElementName); // changed
      $this->startElementNS("p", "TagName", null);
      $this->writeAttribute ("version", "1.0");
      $this->writeAttribute ("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#");
      $this->writeAttribute ("xmlns:p", "http://www.xxxxx.gov.it/sdi/xxxxx/v1.0");
      $this->writeAttribute ("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    }

    /**
    * Set an element with a text to a current xml document.
    * @access public
    * @param string $prm_elementName An element's name
    * @param string $prm_ElementText An element's text
    * @return null
    */
    public function setElement($prm_elementName, $prm_ElementText){
      $this->startElement($prm_elementName);
      $this->text($prm_ElementText);
      $this->endElement();
    }

    /**
    * Construct elements and texts from an array.
    * The array should contain an attribute's name in index part
    * and a attribute's text in value part.
    * @access public
    * @param array $prm_array Contains attributes and texts
    * @return null
    */
    public function fromArray($prm_array){
      if(is_array($prm_array)){
        foreach ($prm_array as $index => $element){
          if(is_array($element)){
            $this->startElement($index);
            $this->fromArray($element);
            $this->endElement();
          }
          else
            $this->setElement($index, $element);

        }
      }
    }

    /**
    * Return the content of a current xml document.
    * @access public
    * @param null
    * @return string Xml document
    */

    public function getDocument(){     
      $this->endElement();
      $this->endDocument();
      return $this->outputMemory();
    }

    /**
    * Output the content of a current xml document.
    * @access public
    * @param null
    */

    public function output(){              
      header('Content-type: text/xml');
      echo $this->getDocument();
    }


    }

    //Example:

    $contents = array(
      'prova' => array(
        "gino" => array(
          "innergino" => "gino inner value",
          "innergino2" => "gino inner another value"
        ),
        "filo" => "filodata",
        "arrays" => array (
          "inner-arrays" => array (
            "one-inner-array" => array (
              "inner-content-one" => "one",
              "inner-content-two" => "two"
            ),
            "two-inner-array" => array (
              "inner-content-one" => "one",
              "inner-content-two" => "two"
            ),
            "three-inner-array" => array (
              "inner-content-one" => "one",
              "inner-content-two" => "two"
            ),
          )
        )
      )
    );

    $XmlConstruct = new XmlConstruct('root');
    $XmlConstruct->fromArray($contents);
    $XmlConstruct->getDocument();           // cahnged

    ?>

输出是:

<?xml version="1.0" encoding="UTF-8"?>
<p:TagName version="1.0" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:p="http://www.xxxxx.gov.it/sdi/xxxxx/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <prova>
    <gino>
      <innergino>gino inner value</innergino>
      <innergino2>gino inner another value</innergino2>
    </gino>
    <filo>filodata</filo>
    <arrays>
       <inner-arrays>
         <one-inner-array>
           <inner-content-one>one</inner-content-one>
           <inner-content-two>two</inner-content-two>
        </one-inner-array>
        <two-inner-array>
          <inner-content-one>one</inner-content-one>
          <inner-content-two>two</inner-content-two>
        </two-inner-array>
        <three-inner-array>
          <inner-content-one>one</inner-content-one>
          <inner-content-two>two</inner-content-two>
        </three-inner-array>
      </inner-arrays>
    </arrays>
  </prova>
</p:TagName>