4

xml形式に変換する必要のある配列があります。

[name] => ABC
[email] => email@email.com
[phones] => Array
                (
                 [phone] => Array
                          (
                                [0] => Array
                                    (
                                        [mobile] => 91454599193
                                        [land] =>  9999999 
                                    )

                                [1] => Array
                                    (
                                        [mobile] => 54520199193
                                        [land] =>  9999999 
                                    )

                                [2] => Array
                                    (
                                        [mobile] => 90424249194
                                        [land] =>  5555555 
                                    )

                                [3] => Array
                                    (
                                        [mobile] => 44224199195
                                        [land] =>  8888888 
                                    )

                            )
)

これを次の形式にしたい

<name>ABC</name>
<email>email@email.com</email>
 <phones>
 <phone>
   <mobile>545450199193</mobile>
   <land>9999999</land>
</phone>
 <phone>
   <mobile>575199193</mobile>
   <land>9999999</land>
</phone>
</phones>

私を助けてください....

これは私の関数であり、このように記述しています。私が直面している問題は、数値を持つインデックスがXMLノードにテキストを表示する必要があることです。例:-以下の電話配列には、インデックス[0]、[1]があります。<phone>XMLページで[0]、[1]を置き換えたい。

  function array_to_xml($value, &$xml_student_info) {
  foreach($value as $key => $value) {
    if(is_array($value)) {
        if(!is_numeric($key)){
            $subnode = $xml_student_info->addChild("$key");
            array_to_xml($value, $subnode);
        }
        else{
            array_to_xml($value, $xml_student_info);
         }
       }
        else {
            $xml_student_info->addChild("$key","$value");
        }
    }
}
4

2 に答える 2

3

再帰を使用して問題を解決できます。再帰は、ネストされたデータをうまく処理します。

これを行うには、値を親 XML 要素に追加する単一の関数を作成します。

その関数は、ネストされたデータを見つけた場合に自分自身を呼び出します。次に、最初に子要素を親に追加し、新しい要素を親として追加して呼び出します。

追加するデータが単なる文字列の場合でも、子を作成しますが、文字列値を直接追加して終了します。それは、せいぜい外側のリーフノードです。

add 関数は、解析するデータを読み取り、4 つのケースのどれを処理するかを見つけるだけで済みます。

  1. 文字列値(名前付き要素の文字列)を持つ新しい要素を追加するだけです
  2. 同じ名前の複数の新しい要素を追加します (名前付き要素の 0-n インデックス付き配列)
  3. 新しい子を追加し、そこに N 個の新しい子を追加します (名前付き要素のキー付き配列)
  4. N 個の新しい子を親に追加します (番号付き (名前なし) 要素のキー付き配列)

この答えについては、匿名関数でこれを試してみるといいと思いました。再帰的にするには、それ自体を参照する必要があります。SimpleXMLElement次に、XML の簡単な作成を可能にする の作成およびインポートを可能にする別の関数内にラップすることができます。さらにラップすると、XML を文字列として生成することもできますが、使用法を明確にするためにそれを外部に保持します。

require('inc/simplexml_pretty_print.php');

$xml      = new SimpleXMLElement('<root/>');
$importer = $createArrayImporter($xml);
echo simplexml_pretty_print($importer($array));

この例$arrayでは、質問の配列です。$add上記の例で呼び出されたときに、別の無名関数内にラップされて返される関数でここで処理されるこれらの 4 つのケースが含まれています$createArrayImporter()

入る前に、入力配列を確認しましょう。

$array = [
    'name'   => 'ABC',
    'email'  => 'email@email.com',
    'phones' =>
    [
        'phone' =>
        [
            [
                'mobile' => '9000199193',
                'land'   => ' 9999999 ',
            ],
            [
                'mobile' => '9000199193',
                'land'   => ' 9999999 ',
            ],
            [
                'mobile' => '9000199194',
                'land'   => ' 5555555 ',
            ],
            [
                'mobile' => '9000199195',
                'land'   => ' 8888888 ',
            ],
        ],
    ],
];

そして、これが作成する出力:

<?xml version="1.0"?>
<root>
  <name>ABC</name>
  <email>email@email.com</email>
  <phones>
    <phone>
      <mobile>9000199193</mobile>
      <land> 9999999 </land>
    </phone>
    <phone>
      <mobile>9000199193</mobile>
      <land> 9999999 </land>
    </phone>
    <phone>
      <mobile>9000199194</mobile>
      <land> 5555555 </land>
    </phone>
    <phone>
      <mobile>9000199195</mobile>
      <land> 8888888 </land>
    </phone>
  </phones>
</root>

そして、再帰関数への方法:

$add = function (SimpleXMLElement $subject, $key, $value) use (&$add)

サブジェクトはデータを追加する XML 要素であり、キーは配列内のキーであり、値はネストされている場合とネストされていない場合がある値です。

したがって、最も単純なケースを考えると、キー付き (すべての配列インデックスは文字列) の配列をルート要素に追加する必要があります。

        case $isKeyed:
            foreach ($value as $oneof_key => $oneof_value) {
                $add($subject, $oneof_key, $oneof_value);
            }

これにより、ネストされた値が渡されます。たとえば、次のレベルの最初は[name] => ABCであるため、キー付き文字列は次のようになります。

        case $isString && $hasKey:
            return $subject->addChild($key, $value);

これは、キーとして指定された文字列値を持つ子要素を追加するだけです。

次のケースは

[phones] => Array
     (
         [phone] => Array
             (
                 ...

これは、名前付き要素のキー付き配列です。

        case $isKeyed && $hasKey:
            $subject = $subject->addChild($key);
            // fall-through intended

ケースに対応する子要素として独自のキーを追加する必要があり$isString && $hasKeyますが、その配列値をさらに処理する必要があります。これは、同じ名前の複数の要素を追加できるように、インデックス付きの子 (インデックスとして 0-N) を持つキー付き配列のネストされたケースでもあります。

        case $isKeyed:
            foreach ($value as $oneof_key => $oneof_value) {
                $add($subject, $oneof_key, $oneof_value);
            }
            return true;

それはそのケースを通過し、キーを持たないが番号付けされているだけのキー付き配列の 4 番目のケースも作成します。

それが、彼が 3 つ半のケースであると書いた理由でもあります。最後の 2 つのケースは、互いにいくつかの部分を共有しています。

これをクロージャー内にラップすると、アクセスしやすくなります。ここでは、簡単な例で概説します。

$createArrayImporter = function (SimpleXMLElement $subject) {

    $add = function (SimpleXMLElement $subject, $key, $value) use (&$add) {

         ...

    };

    return function (Array $array) use ($subject, $add) {

        $add($subject, null, $array);
        return $subject;
    };
};

したがって、これは物事を開始することができます。Gist of mineで完全なコードを読むことができます。

同様の例が見つかりますが、次の回答ではよりオブジェクト指向であり、再帰によっても解決されます。

配列の形式は、似ているように見えても、実際にはあなたのものとは異なります。

その他のポインタについては、次のとおりです。

さまざまなタイプの配列を XML に変換します。

于 2013-01-03T17:12:49.557 に答える
0

問題は、1 つの配列またはオブジェクトに同じキーを含めることができないことです。simplexml の場合、xml が保存されるオブジェクトがあります。解決策は、自分でxmlを構築することです。

于 2013-01-03T10:54:01.523 に答える