2011-09-30 19 views

答えて

8

JSONは、PHP配列、整数、文字列などをネイティブに表現できます。 XMLには、要素、属性、テキストなどの概念はありません。オブジェクトをそのまま転送する場合は、JSONを使用してください。複雑なAPIを実装する場合は、XMLを使用します(例:php DOM interface)。

7

あなたはこのようなあなたはxmlrpc_encodeを使用することができ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)); 
     } 
    } 
} 
+3

細かいことに注意してください。タグ名が 's'で終わっていると、それは自動的に単数形のタグを作り、それを内部に追加します。 (例えば、 'coordinate'タグを持たないkmlを作成するときにそれを試してみてください):-P – MortenSickel

4

から1を独自のxml_encode()関数を定義することができます。

xmlrpc_encode ($your_array); 

この機能は実験的なので注意してください。

リファレンス

$str = htmlentities($str , ENT_XML1); 

ドキュメント:http://php.net/manual/en/function.xmlrpc-encode.php

+0

これはnoce関数ですが、時には不安定になることがあります。 – iJamesPHP

1
ここ

php7.0の+のための1つである、私はそれが最適にはほど遠い賭けますコードはささいなことではなく、ですが、少なくともSephのコードとは異なり、私のデータで動作します...

例:

$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> 

機能: - 編集:空の配列をコードするバグを修正。

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 ("\n", $full) as $line) { 
      if (substr ($line, 0, 2) === ' ') { 
       $ret .= substr ($line, 2) . "\n"; 
      } else { 
       $ret .= $line . "\n"; 
      } 
     } 
     $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(); 
       $tmp = @DOMDocument::loadXML ('<root>' . $tmp . '</root>'); 
       foreach ($tmp->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); 
       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; 
} 
+1

少し遅れますが、doctypeまたはaルート要素が不正に生成されたXMLになった場合、 'return $ ret;'を 'return '<?xml version =" 1.0 "encoding =" UTF-8 "?>'に置き換えることができます。 $ ret。 ''; ' – Ben

関連する問題