0
<?php
/*
    Sample: $results = XMLParser::load('<xml ....');
            $results = XMLParser::load(VSCHEMAS.'/Users.edit.xml');
*/

    /**
     * Abstract XMLParser class. A non-instantiable class that uses SimpleXML to parse XML, based on a path or body passed into the load method
     * 
     * @abstract
     */
    abstract class XMLParser {

        /**
         * convert function. Converts a SimpleXMLElement object to an associative array, usable for iteration
         * 
         * @see http://www.if-not-true-then-false.com/2009/12/php-tip-convert-stdclass-object-to-multidimensional-array-and-convert-multidimensional-array-to-stdclass-object/
         * @access private
         * @static
         * @param mixed $node node to convert to a non-object based value
         * @return array associative array of the passed in node/object, ultimately representing the initially passed in object as an associative array
         */
        private static function convert($node) {
            if(is_object($node))
                $node = get_object_vars($node);
            if(is_array($node))
                return array_map(array('self', 'convert'), $node);
            return $node;
        }

        /**
         * load function. Loads a source (either a local path or source body) document, and returns as associative array of it's results
         * 
         * @access public
         * @static
         * @param string $source xml body, or path to local xml file
         * @return array SimpleXML results, parsed as an associative array
         */
        public static function load($source) {
            $path = false;
            if(preg_match('/^\//', $source) > 0)
                $path = true;
            $simpleXMLElement = new SimpleXMLElement($source, LIBXML_NOENT, $path);
            return self::convert($simpleXMLElement);
        }
    }

?>

上記のコードを使用して xml ファイルを解析し、それらをよりトラバース可能な配列に変換しています。しかし、私は問題に直面しています。次のようなサンプル xml がある場合:

<fields>
    <rule whatever="lolcats" />
</fields>

対。

<fields>
    <rule whatever="lolcats" />
    <rule whatever="lolcats" />
</fields>

結果の配列は一貫していません。つまり、最初のケースでは、次の形式です。

Array
(
    [field] => Array
        (
            [@attributes]...

後者では、次の形式です。

Array
(
    [field] => Array
        (
            [0]...

私がここで言っているのは、サブ xml 要素を数値でインデックス付けしているということです。これは私が望むものですが、1 つ以上ある場合にのみです。直接ではなく、常に数値でインデックス付けするために何を変更するかについての考え唯一の要素の @attributes 配列への参照?

どんな助けでも大歓迎です:D

4

2 に答える 2

0

int単純に配列キーをテストしてから、0期待する配列を偽造するだけの要素または属性を持つことはできません。

于 2010-01-19T01:47:27.663 に答える
0

ブーム!私は以下のコードを数時間いじり、ついにエディターからノックアウトしました! トリックは、値が参照されている vars をループすることでした。それが実際にオブジェクトであるが、キーが「@attributes」ではなかった場合 (上記のように)、それを配列にラップします:D

/**
 * convert function. Converts a SimpleXMLElement object to an associative array, usable for iteration
 * 
 * @see http://www.if-not-true-then-false.com/2009/12/php-tip-convert-stdclass-object-to-multidimensional-array-and-convert-multidimensional-array-to-stdclass-object/
 * @access private
 * @static
 * @param mixed $node node to convert to a non-object based value
 * @return array associative array of the passed in node/object, ultimately representing the initially passed in object as an associative array
 */
private static function convert($node) {
    if(is_object($node)) {
        $vars = get_object_vars($node);
        foreach($vars as $key => &$var) {
            if($key!=='@attributes' && is_object($var))
                $var = array($var);
        }
        $node = $vars;
    }
    if(is_array($node))
        return array_map(array('self', 'convert'), $node);
    return $node;
}
于 2010-01-19T02:23:51.637 に答える