php Array2Xml子数组正在循环,而不是成为父数组

osh3o9ms  于 2023-05-27  发布在  PHP
关注(0)|答案(1)|浏览(198)

我试图使xml中的一个节点成为所有其他节点的父节点,只是由于某种原因,它成为每个节点的父节点,而不是全局父节点。
当前输出-正如您所看到的,数据在每次测验中不断重复。

<?xml version="1.0" encoding="UTF-8"?>
<wpProQuiz>
  <header version="0.28" exportVersion="1"/>
  <data>
    <quiz>
      <title titleHidden="true"><![CDATA[Module 1]]></title>
      <text><![CDATA[On your marks....]]></text>
    </quiz>
  </data>
  <data>
    <quiz>
      <title titleHidden="true"><![CDATA[Module 2]]></title>
      <text><![CDATA[On your marks....]]></text>
    </quiz>
  </data>
  <data>
    <quiz>
      <title titleHidden="true"><![CDATA[Module 3]]></title>
      <text><![CDATA[On your marks....]]></text>
    </quiz>
  </data>
</wpProQuiz>

预期输出-数据应该保持父数组,因为它是在php这样。

<?xml version="1.0" encoding="UTF-8"?>
<wpProQuiz>
  <header version="0.28" exportVersion="1"/>
  <data>
    <quiz>
      <title titleHidden="true"><![CDATA[Module 1]]></title>
      <text><![CDATA[On your marks....]]></text>
    </quiz>
    <quiz>
      <title titleHidden="true"><![CDATA[Module 2]]></title>
      <text><![CDATA[On your marks....]]></text>
    </quiz>
    <quiz>
      <title titleHidden="true"><![CDATA[Module 3]]></title>
      <text><![CDATA[On your marks....]]></text>
    </quiz>
  </data>
</wpProQuiz>

PHP代码+Array 2XML类

<?php
    class Array2XML {
        private static $xml = null;
        private static $encoding = 'UTF-8';
        public static function init($version = '1.0', $encoding = 'UTF-8', $format_output = true) {
            self::$xml = new DomDocument($version, $encoding);
            self::$xml->formatOutput = $format_output;
            self::$encoding = $encoding;
        }
        public static function &createXML($node_name, $arr=array()) {
            $xml = self::getXMLRoot();
            $xml->appendChild(self::convert($node_name, $arr));

            self::$xml = null;
            return $xml;
        }
        private static function &convert($node_name, $arr=array()) {
            $xml = self::getXMLRoot();
            $node = $xml->createElement($node_name);

            if(is_array($arr)){
                if(isset($arr['@attributes'])) {
                    foreach($arr['@attributes'] as $key => $value) {
                        if(!self::isValidTagName($key)) {
                            throw new Exception('[Array2XML] Illegal character in attribute name. attribute: '.$key.' in node: '.$node_name);
                        }
                        $node->setAttribute($key, self::bool2str($value));
                    }
                    unset($arr['@attributes']);
                }
                if(isset($arr['@value'])) {
                    $node->appendChild($xml->createTextNode(self::bool2str($arr['@value'])));
                    unset($arr['@value']);
                    return $node;
                } else if(isset($arr['@cdata'])) {
                    $node->appendChild($xml->createCDATASection(self::bool2str($arr['@cdata'])));
                    unset($arr['@cdata']);
                    return $node;
                }
            }

            if(is_array($arr)){
                foreach($arr as $key=>$value){
                    if(!self::isValidTagName($key)) {
                        throw new Exception('[Array2XML] Illegal character in tag name. tag: '.$key.' in node: '.$node_name);
                    }
                    if(is_array($value) && is_numeric(key($value))) {
                        foreach($value as $k=>$v){
                            $node->appendChild(self::convert($key, $v));
                        }
                    } else {
                        $node->appendChild(self::convert($key, $value));
                    }
                    unset($arr[$key]);
                }
            }
            if(!is_array($arr)) {
                $node->appendChild($xml->createTextNode(self::bool2str($arr)));
            }

            return $node;
        }
        private static function getXMLRoot(){
            if(empty(self::$xml)) {
                self::init();
            }
            return self::$xml;
        }
        private static function bool2str($v){
            $v = $v === true ? 'true' : $v;
            $v = $v === false ? 'false' : $v;
            return $v;
        }
        private static function isValidTagName($tag){
            $pattern = '/^[a-z_]+[a-z0-9\:\-\.\_]*[^:]*$/i';
            return preg_match($pattern, $tag, $matches) && $matches[0] == $tag;
        }
    }
    $module = 3;
    $data = array(
                'header' => array(
                            '@attributes' => array(
                                'version' => '0.28',
                                'exportVersion' => '1',
                            ),
                ),
                'data' => array(
                    'quiz' => array(
                        'title' => array(
                                    '@attributes' => array(
                                        'titleHidden' => 'true'
                                    ),
                                    '@value' => '<![CDATA[Module '.$module.']]>',
                                  ),
                        'text' => '<![CDATA[On your marks....]]>',
                    )
                )
            );
    $generate_modules = $data['data']['quiz'];
    $generate_modules['questions'] = [''];
    $total_generated_modules = [];
    for($i = 1; $i < $module; $i++) {
        $generate_modules['title']['@value'] = '<![CDATA[Module '.$i.']]>';
        $total_generated_modules[]['quiz'] = $generate_modules;
    }
    $header['header'] = $data['header'];
    //$body['data'] = $total_generated_modules;
    $m = 0;
    foreach($total_generated_modules as $tgm) {
        $body['data'][$m] = $tgm;
        $m++;
    }
    $last['data'][$m] = $data['data'];
    $total = array_merge_recursive($header, $body, $last);
    $xml = Array2XML::createXML('wpProQuiz', $total);       
?>

UPDATEvar_dump($total)

array (size=2)
  'header' => 
    array (size=1)
      '@attributes' => 
        array (size=2)
          'version' => string '0.28' (length=4)
          'exportVersion' => string '1' (length=1)
  'data' => 
    array (size=3)
      0 => 
        array (size=1)
          'quiz' => 
            array (size=38)
              'title' => 
                array (size=2)
                  '@attributes' => 
                    array (size=1)
                      'titleHidden' => string 'true' (length=4)
                  '@value' => string '<![CDATA[Module 1]]>' (length=20)
              'text' => string '<![CDATA[On your marks....]]>' (length=29)
      1 => 
        array (size=1)
          'quiz' => 
            array (size=38)
              'title' => 
                array (size=2)
                  '@attributes' => 
                    array (size=1)
                      'titleHidden' => string 'true' (length=4)
                  '@value' => string '<![CDATA[Module 2]]>' (length=20)
              'text' => string '<![CDATA[On your marks....]]>' (length=29)

      2 => 
        array (size=1)
          'quiz' => 
            array (size=38)
              'title' => 
                array (size=2)
                  '@attributes' => 
                    array (size=1)
                      'titleHidden' => string 'true' (length=4)
                  '@value' => string '<![CDATA[Module 2]]>' (length=20)
              'text' => string '<![CDATA[On your marks....]]>' (length=29)
kiayqfof

kiayqfof1#

只是在使用Array2XML时遇到了同样的问题
这里我找到的解决方案是,创建一个相同的子参数(在本例中为<quiz>),而不用关闭</data>并重新打开<data>

$data = array(
'header' => array(
    '@attributes' => array(
        'version' => '0.28',
        'exportVersion' => '1',
    ),
),
'data' => array(
    'quiz' => array(
        array(
            'title' => array(
                '@attributes' => array(
                    'titleHidden' => 'true',
                ),
                '@cdata' => 'Module 1',
            ),
            'text' => array(
                '@cdata' => 'On your marks....',
            ),
        ),
        array(
            'title' => array(
                '@attributes' => array(
                    'titleHidden' => 'true'
                ),
                '@cdata' => 'Module 2',
            ),
            'text' => array(
                '@cdata' => 'On your marks....',
            ),
        ),
        array(
            'title' => array(
                '@attributes' => array(
                    'titleHidden' => 'true'
                ),
                '@cdata' => 'Module 3',
            ),
            'text' => array(
                '@cdata' => 'On your marks....',
            ),
        ),
    )
)

);

相关问题