代码之家  ›  专栏  ›  技术社区  ›  uomopalese

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

  •  0
  • uomopalese  · 技术社区  · 10 年前

    我在关注 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 回复  |  直到 10 年前
        1
  •  0
  •   Community Mr_and_Mrs_D    7 年前

    最后,(在阅读了很多页面并尝试了很多示例之后),我按照自己的方式找到了解决方案。首先 as explained in this post , XMLWriter 是大型xml文件的最佳选择(就像我的情况一样),这就是为什么在深入研究之后,我没有遵循由提出的基于DOM的解决方案 @Seyed Quarib ,尽管读这篇文章很有启发性。另一个问题是,我的所有xml内容都需要包装在一个带有如下名称空间的标记中 <p:TagName> .我发现我需要使用 XMLWriter::startElementNS 而且 XMLWriter::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>