English 中文(简体)
在PHP中是否有类似于json_encode()。
原标题:Is there an xml_encode() like json_encode() in PHP?
  • 时间:2011-09-30 10:28:55
  •  标签:
  • php
  • xml
  • ajax

In PHP, it is easy to pass back JSON objects by using the json_encode() function.

是否有相应的XML?

最佳回答

JSON能够以本地方式表达其阵列、愤怒、扼杀等。 XML没有这种概念——只是要素、属性和案文。 如果您想逐字转交反对,请使用JSON。 如果你想要实施复杂的亚特兰大,则使用XML,例如: phpDOM界面

问题回答

You can define your own xml_encode() function such as this the one from http://darklaunch.com/2009/05/23/php-xml-encode-using-domdocument-convert-array-to-xml-json-encode

function xml_encode($mixed, $domElement=null, $DOMDocument=null) {
    if (is_null($DOMDocument)) {
        $DOMDocument =new DOMDocument;
        $DOMDocument->formatOutput = true;
        xml_encode($mixed, $DOMDocument, $DOMDocument);
        echo $DOMDocument->saveXML();
    }
    else {
        // To cope with embedded objects 
        if (is_object($mixed)) {
          $mixed = get_object_vars($mixed);
        }
        if (is_array($mixed)) {
            foreach ($mixed as $index => $mixedElement) {
                if (is_int($index)) {
                    if ($index === 0) {
                        $node = $domElement;
                    }
                    else {
                        $node = $DOMDocument->createElement($domElement->tagName);
                        $domElement->parentNode->appendChild($node);
                    }
                }
                else {
                    $plural = $DOMDocument->createElement($index);
                    $domElement->appendChild($plural);
                    $node = $plural;
                    if (!(rtrim($index,  s ) === $index)) {
                        $singular = $DOMDocument->createElement(rtrim($index,  s ));
                        $plural->appendChild($singular);
                        $node = $singular;
                    }
                }

                xml_encode($mixedElement, $node, $DOMDocument);
            }
        }
        else {
            $mixed = is_bool($mixed) ? ($mixed ?  true  :  false ) : $mixed;
            $domElement->appendChild($DOMDocument->createTextNode($mixed));
        }
    }
}

You could use xmlrpc_encode.

 xmlrpc_encode ($your_array);

Be careful because this function is EXPERIMENTAL.

Reference: http://php.net/manual/en/function.xmlrpc-encode.php

here is one for php7.0+ , i bet it is far from optimal , the code is non-trivial, and it has NOT been tested much, but at least it works for my data (unlike Seph s code)...

example:

$test = array (
         normal1  =>  foo ,
         normal2  =>  bar ,
         foo_assoc  => [ 
                 foo ,
                 bar ,
                 baz ,
                [ 
                         derp ,
                         derpmore  
                ] 
        ],
         foo_nonassoc  => [ 
                 derppp  =>  yes ,
                 daarpp  =>  no ,
                 lel ,
                 far  =>  away  
        ],
         normal3  =>  lala ,
         deep  => [ 
                 deeper  => [ 
                         deeper2  => [ 
                                 deepest  => [ 
                                         quite ,
                                         deep ,
                                         indeed  
                                ],
                                 checkmate  
                        ] 
                ] 
        ],
         special  =>  encoding<special>characters&test ,
         me_n_you  =>  true  
);

echo (hhb_xml_encode ( $test ));

产出:

<normal1>foo</normal1>
<normal2>bar</normal2>
<foo_assoc>foo</foo_assoc>
<foo_assoc>bar</foo_assoc>
<foo_assoc>baz</foo_assoc>
<foo_assoc>derp</foo_assoc>
<foo_assoc>derpmore</foo_assoc>
<foo_nonassoc>
  <derppp>yes</derppp>
  <daarpp>no</daarpp>
  <foo_nonassoc>lel</foo_nonassoc>
  <far>away</far>
</foo_nonassoc>
<normal3>lala</normal3>
<deep>
  <deeper>
    <deeper2>
      <deepest>quite</deepest>
      <deepest>deep</deepest>
      <deepest>indeed</deepest>
      <deeper2>checkmate</deeper2>
    </deeper2>
  </deeper>
</deep>
<special>encoding&lt;special&gt;characters&amp;test</special>
<me_n_you>true</me_n_you>

职能:

  • Edit: fixed a bug with encoding empty arrays.
  • Edit: made the code PHP8-compatible
    function hhb_xml_encode(array $arr, string $name_for_numeric_keys =  val ): string {
        if (empty ( $arr )) {
            // avoid having a special case for <root/> and <root></root> i guess
            return   ;
        }
        $is_iterable_compat = function ($v): bool {
            // php 7.0 compat for php7.1+ s is_itrable
            return is_array ( $v ) || ($v instanceof Traversable);
        };
        $isAssoc = function (array $arr): bool {
            // thanks to Mark Amery for this
            if (array () === $arr)
                return false;
            return array_keys ( $arr ) !== range ( 0, count ( $arr ) - 1 );
        };
        $endsWith = function (string $haystack, string $needle): bool {
            // thanks to MrHus
            $length = strlen ( $needle );
            if ($length == 0) {
                return true;
            }
            return (substr ( $haystack, - $length ) === $needle);
        };
        $formatXML = function (string $xml) use ($endsWith): string {
            // there seems to be a bug with formatOutput on DOMDocuments that have used importNode with $deep=true
            // on PHP 7.0.15...
            $domd = new DOMDocument (  1.0 ,  UTF-8  );
            $domd->preserveWhiteSpace = false;
            $domd->formatOutput = true;
            $domd->loadXML (  <root>  . $xml .  </root>  );
            $ret = trim ( $domd->saveXML ( $domd->getElementsByTagName ( "root" )->item ( 0 ) ) );
            assert ( 0 === strpos ( $ret,  <root>  ) );
            assert ( $endsWith ( $ret,  </root>  ) );
            $full = trim ( substr ( $ret, strlen (  <root>  ), - strlen (  </root>  ) ) );
            $ret =   ;
            // ... seems each line except the first line starts with 2 ugly spaces,
            // presumably its the <root> element that starts with no spaces at all.
            foreach ( explode ( "
", $full ) as $line ) {
                if (substr ( $line, 0, 2 ) ===     ) {
                    $ret .= substr ( $line, 2 ) . "
";
                } else {
                    $ret .= $line . "
";
                }
            }
            $ret = trim ( $ret );
            return $ret;
        };
        
        // $arr = new RecursiveArrayIterator ( $arr );
        // $iterator = new RecursiveIteratorIterator ( $arr, RecursiveIteratorIterator::SELF_FIRST );
        $iterator = $arr;
        $domd = new DOMDocument ();
        $root = $domd->createElement (  root  );
        foreach ( $iterator as $key => $val ) {
            // var_dump ( $key, $val );
            $ele = $domd->createElement ( is_int ( $key ) ? $name_for_numeric_keys : $key );
            if (! empty ( $val ) || $val ===  0 ) {
                if ($is_iterable_compat ( $val )) {
                    $asoc = $isAssoc ( $val );
                    $tmp = hhb_xml_encode ( $val, is_int ( $key ) ? $name_for_numeric_keys : $key );
                    // var_dump ( $tmp );
                    // die ();
                    $tmpDom = new DOMDocument();
                    @$tmpDom->loadXML (  <root>  . $tmp .  </root>  );
                    foreach ( $tmpDom->getElementsByTagName ( "root" )->item ( 0 )->childNodes ?? [ ] as $tmp2 ) {
                        $tmp3 = $domd->importNode ( $tmp2, true );
                        if ($asoc) {
                            $ele->appendChild ( $tmp3 );
                        } else {
                            $root->appendChild ( $tmp3 );
                        }
                    }
                    unset ( $tmp, $tmp2, $tmp3, $tmpDom );
                    if (! $asoc) {
                        // echo  REMOVING ;die();
                        // $ele->parentNode->removeChild($ele);
                        continue;
                    }
                } else {
                    $ele->textContent = $val;
                }
            }
            $root->appendChild ( $ele );
        }
        $domd->preserveWhiteSpace = false;
        $domd->formatOutput = true;
        $ret = trim ( $domd->saveXML ( $root ) );
        assert ( 0 === strpos ( $ret,  <root>  ) );
        assert ( $endsWith ( $ret,  </root>  ) );
        $ret = trim ( substr ( $ret, strlen (  <root>  ), - strlen (  </root>  ) ) );
        // seems to be a bug with formatOutput on DOMDocuments that have used importNode with $deep=true..
        $ret = $formatXML ( $ret );
        return $ret;
    }

我反对:

function xml_encode(mixed $value=null, string $key="root", SimpleXMLElement $parent=null){
    if(is_object($value)) $value = (array) $value;
    if(!is_array($value)){
        if($parent === null){   
            if(is_numeric($key)) $key =  item ;             
            if($value===null) $node = new SimpleXMLElement("<$key />");
            else              $node = new SimpleXMLElement("<$key>$value</$key>");
        }
        else{
            $parent->addChild($key, $value);
            $node = $parent;
        }
    }
    else{
        $array_numeric = false;
        if($parent === null){ 
            if(empty($value)) $node = new SimpleXMLElement("<$key />");
            else              $node = new SimpleXMLElement("<$key></$key>");
        }
        else{
            if(!isset($value[0])) $node = $parent->addChild($key);
            else{
                $array_numeric = true;
                $node = $parent;
            }
        }
        foreach( $value as $k => $v ) {
            if($array_numeric) xml_encode($v, $key, $node);
            else xml_encode($v, $k, $node);
        }
    }       
    return $node;
}

简单例子:

   $a = "hello";
   $xml_element = xml_encode($a, a );
   echo $xml_element->asXML();

Null Example:

   $xml_element = xml_encode(null, example );
   echo $xml_element->asXML();

Complex Example:

   $w = new stdClass();
   $w->special = true;
   $w->name =  Birthday Susan ;
    
   $v = new stdClass();
   $v->name =  John ;
   $v->surname =  Smith ;
   $v->hobbies = array( soccer , cinema );
   $v->job =  policeman ;
   $v->events = new stdClass();
   $v->events->tomorrow = false;
   $v->events->yesterday = true;
   $v->events->list = array($v->hobbies, $w);
    
   $xml_element = xml_encode($v, oembed );
   echo $xml_element->asXML();

This works for me in most cases:

$str = htmlentities($str , ENT_XML1);

Docs: http://php.net/manual/en/function.htmlentities.php





相关问题
ajax login using httpRequest?

I am trying to develop my login script to give feedback to the user if the login is valid or not. Basically if it isn t correct a div box will show saying its wrong, if its correct it will show its ...

Virtual Tour using sketch up, ajax, flash technologies

I want to know if there are existing technology that make your 3d models in sketch into virtual tours, using either Ajax or Flash for web presentation. If there s none, which will be a good approach ...

How can i update div continuously

I have asp.net application where i have a div which showing the value from other site. The value of that site is changing continuously. I want that my div will automatically update in some interval ...

热门标签