50

特定のPHPオブジェクトを取得してXMLとしてシリアル化する最良の方法は何ですか? 私は simple_xml を見ていて、それを使用して XML をオブジェクトに解析しましたが、それが逆にどのように機能するかは明確ではありません。

4

12 に答える 12

53

PEAR の XML_Serializer を使用することに同意しますが、ネストされたプロパティを持つオブジェクト/配列をサポートする単純なものが必要な場合は、これを使用できます。

class XMLSerializer {

    // functions adopted from http://www.sean-barton.co.uk/2009/03/turning-an-array-or-object-into-xml-using-php/

    public static function generateValidXmlFromObj(stdClass $obj, $node_block='nodes', $node_name='node') {
        $arr = get_object_vars($obj);
        return self::generateValidXmlFromArray($arr, $node_block, $node_name);
    }

    public static function generateValidXmlFromArray($array, $node_block='nodes', $node_name='node') {
        $xml = '<?xml version="1.0" encoding="UTF-8" ?>';

        $xml .= '<' . $node_block . '>';
        $xml .= self::generateXmlFromArray($array, $node_name);
        $xml .= '</' . $node_block . '>';

        return $xml;
    }

    private static function generateXmlFromArray($array, $node_name) {
        $xml = '';

        if (is_array($array) || is_object($array)) {
            foreach ($array as $key=>$value) {
                if (is_numeric($key)) {
                    $key = $node_name;
                }

                $xml .= '<' . $key . '>' . self::generateXmlFromArray($value, $node_name) . '</' . $key . '>';
            }
        } else {
            $xml = htmlspecialchars($array, ENT_QUOTES);
        }

        return $xml;
    }

}
于 2010-02-03T19:21:25.270 に答える
39

PEARのXML_Serializerパッケージを見てください。私はそれをかなり良い結果で使用しました。配列やオブジェクトなどをフィードすると、XMLに変換されます。また、ルートノードの名前を選択するなどのオプションもたくさんあります。

トリックを行う必要があります

于 2008-09-26T00:15:11.903 に答える
10

元の質問に対する完全な答えではありませんが、これに関する問題を解決する方法は、オブジェクトを次のように宣言することでした。

$root = '<?xml version="1.0" encoding="UTF-8"?><Activities/>';
$object = new simpleXMLElement($root); 

とは対照的に:

$object = new stdClass;

値を追加する前に!

于 2010-01-21T09:35:42.453 に答える
7

それを行うには、dom 関数を使用します: http://www.php.net/manual/en/function.dom-import-simplexml.php

SimpleXML オブジェクトをインポートして保存します。上記のリンクには例が含まれています。:)

手短に:

<?php
$array = array('hello' => 'world', 'good' => 'morning');

$xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><foo />");
foreach ($array as $k=>$v) {
  $xml->addChild($k, $v);
}
?>
于 2008-09-26T00:10:20.433 に答える
3

私のバージョンを見てください

    class XMLSerializer {

    /**
     * 
     * The most advanced method of serialization.
     * 
     * @param mixed $obj => can be an objectm, an array or string. may contain unlimited number of subobjects and subarrays
     * @param string $wrapper => main wrapper for the xml
     * @param array (key=>value) $replacements => an array with variable and object name replacements
     * @param boolean $add_header => whether to add header to the xml string
     * @param array (key=>value) $header_params => array with additional xml tag params
     * @param string $node_name => tag name in case of numeric array key
     */
    public static function generateValidXmlFromMixiedObj($obj, $wrapper = null, $replacements=array(), $add_header = true, $header_params=array(), $node_name = 'node') 
    {
        $xml = '';
        if($add_header)
            $xml .= self::generateHeader($header_params);
        if($wrapper!=null) $xml .= '<' . $wrapper . '>';
        if(is_object($obj))
        {
            $node_block = strtolower(get_class($obj));
            if(isset($replacements[$node_block])) $node_block = $replacements[$node_block];
            $xml .= '<' . $node_block . '>';
            $vars = get_object_vars($obj);
            if(!empty($vars))
            {
                foreach($vars as $var_id => $var)
                {
                    if(isset($replacements[$var_id])) $var_id = $replacements[$var_id];
                    $xml .= '<' . $var_id . '>';
                    $xml .= self::generateValidXmlFromMixiedObj($var, null, $replacements,  false, null, $node_name);
                    $xml .= '</' . $var_id . '>';
                }
            }
            $xml .= '</' . $node_block . '>';
        }
        else if(is_array($obj))
        {
            foreach($obj as $var_id => $var)
            {
                if(!is_object($var))
                {
                    if (is_numeric($var_id)) 
                        $var_id = $node_name;
                    if(isset($replacements[$var_id])) $var_id = $replacements[$var_id]; 
                    $xml .= '<' . $var_id . '>';    
                }   
                $xml .= self::generateValidXmlFromMixiedObj($var, null, $replacements,  false, null, $node_name);
                if(!is_object($var))
                    $xml .= '</' . $var_id . '>';
            }
        }
        else
        {
            $xml .= htmlspecialchars($obj, ENT_QUOTES);
        }

        if($wrapper!=null) $xml .= '</' . $wrapper . '>';

        return $xml;
    }   

    /**
     * 
     * xml header generator
     * @param array $params
     */
    public static function generateHeader($params = array())
    {
        $basic_params = array('version' => '1.0', 'encoding' => 'UTF-8');
        if(!empty($params))
            $basic_params = array_merge($basic_params,$params);

        $header = '<?xml';
        foreach($basic_params as $k=>$v)
        {
            $header .= ' '.$k.'='.$v;
        }
        $header .= ' ?>';
        return $header;
    }    
}
于 2013-04-04T13:33:30.940 に答える
2

WDDX を使用: http://uk.php.net/manual/en/wddx.examples.php

(この拡張機能がインストールされている場合)

それはそれに専念しています:

http://www.openwddx.org/

于 2008-09-27T10:01:02.413 に答える
0

次のように、再帰的な方法を使用します。

private function ReadProperty($xmlElement, $object) {
    foreach ($object as $key => $value) {
        if ($value != null) {
            if (is_object($value)) {
                $element = $this->xml->createElement($key);
                $this->ReadProperty($element, $value);
                $xmlElement->AppendChild($element);
            } elseif (is_array($value)) {
                $this->ReadProperty($xmlElement, $value);
            } else {
                $this->AddAttribute($xmlElement, $key, $value);
            }
        }
    }
}

完全な例: http://www.tyrodeveloper.com/2018/09/convertir-clase-en-xml-con-php.html

于 2018-09-15T23:04:08.870 に答える
-1

@philfreo と、PEAR に依存すべきではないという彼の論拠には同意しますが、彼の解決策はまだ十分ではありません。キーが次の文字のいずれかを含む文字列である可能性がある場合、問題が発生する可能性があります。

  • <
  • >
  • \s (スペース)
  • "
  • '

XML は文法でこれらの文字を使用するため、これらのいずれかがフォーマットから外れます。したがって、これ以上苦労することなく、非常に起こりうる発生に対する簡単な解決策を次に示します。

function xml_encode( $var, $indent = false, $i = 0 ) {
    $version = "1.0";
    if ( !$i ) {
        $data = '<?xml version="1.0"?>' . ( $indent ? "\r\n" : '' )
                . '<root vartype="' . gettype( $var ) . '" xml_encode_version="'. $version . '">' . ( $indent ? "\r\n" : '' );
    }
    else {
        $data = '';
    }

    foreach ( $var as $k => $v ) {
        $data .= ( $indent ? str_repeat( "\t", $i ) : '' ) . '<var vartype="' .gettype( $v ) . '" varname="' . htmlentities( $k ) . '"';

        if($v == "") {
            $data .= ' />';
        }
        else {
            $data .= '>';
            if ( is_array( $v ) ) {
                $data .= ( $indent ? "\r\n" : '' ) . xml_encode( $v, $indent, $verbose, ($i + 1) ) . ( $indent ? str_repeat("\t", $i) : '' );
            }
            else if( is_object( $v ) ) {
                $data .= ( $indent ? "\r\n" : '' ) . xml_encode( json_decode( json_encode( $v ), true ), $indent, $verbose, ($i + 1)) . ($indent ? str_repeat("\t", $i) : '');
            }
            else {
                $data .= htmlentities( $v );
            }

            $data .= '</var>';
        }

        $data .= ($indent ? "\r\n" : '');
    }

    if ( !$i ) {
        $data .= '</root>';
    }

    return $data;
}

使用例を次に示します。

// sample object
$tests = Array(
    "stringitem" => "stringvalue",
    "integeritem" => 1,
    "floatitem" => 1.00,
    "arrayitems" =>  Array("arrayvalue1", "arrayvalue2"),
    "hashitems" => Array( "hashkey1" => "hashkey1value", "hashkey2" => "hashkey2value" ),
    "literalnull" => null,
    "literalbool" => json_decode( json_encode( 1 ) )
);
// add an objectified version of itself as a child
$tests['objectitem'] = json_decode( json_encode( $tests ), false);

// convert and output
echo xml_encode( $tests );

/*
// output:

<?xml version="1.0"?>
<root vartype="array" xml_encode_version="1.0">
<var vartype="integer" varname="integeritem">1</var>
<var vartype="string" varname="stringitem">stringvalue</var>
<var vartype="double" varname="floatitem">1</var>
<var vartype="array" varname="arrayitems">
    <var vartype="string" varname="0">arrayvalue1</var>
    <var vartype="string" varname="1">arrayvalue2</var>
</var>
<var vartype="array" varname="hashitems">
    <var vartype="string" varname="hashkey1">hashkey1value</var>
    <var vartype="string" varname="hashkey2">hashkey2value</var>
</var>
<var vartype="NULL" varname="literalnull" />
<var vartype="integer" varname="literalbool">1</var>
<var vartype="object" varname="objectitem">
    <var vartype="string" varname="stringitem">stringvalue</var>
    <var vartype="integer" varname="integeritem">1</var>
    <var vartype="integer" varname="floatitem">1</var>
    <var vartype="array" varname="arrayitems">
        <var vartype="string" varname="0">arrayvalue1</var>
        <var vartype="string" varname="1">arrayvalue2</var>
    </var>
    <var vartype="array" varname="hashitems">
        <var vartype="string" varname="hashkey1">hashkey1value</var>
        <var vartype="string" varname="hashkey2">hashkey2value</var>
    </var>
    <var vartype="NULL" varname="literalnull" />
    <var vartype="integer" varname="literalbool">1</var>
</var>
</root>

*/

キー名は varname 属性 (html エンコード) に格納され、型も格納されるため、対称的な逆シリアル化が可能であることに注意してください。これには 1 つだけ問題があります。クラスはシリアル化されず、インスタンス化されたオブジェクトのみがシリアル化され、クラス メソッドは含まれません。これは、「データ」をやり取りする場合にのみ機能します。

これはずっと前に答え​​られましたが、これが誰かに役立つことを願っています。

于 2011-07-26T23:59:32.033 に答える
-2

まあ、少し汚いですが、オブジェクトのプロパティでいつでもループを実行できます...

$_xml = '';
foreach($obj as $key => $val){
  $_xml .= '<' . $key . '>' . $val . '</' . $key . ">\n";
}

$_xmlfopen / fwrite / fcloseを使用すると、変数をコンテンツとして使用してXMLドキュメントを生成できます。それは醜いですが、それはうまくいくでしょう。

于 2008-09-26T00:12:48.663 に答える