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]...

我在这里要说的是,它以数字方式索引 sub-xml 元素,这是我想要的,但只有当超过 1 时。关于改变什么以始终以数字方式索引它们的任何想法,而不是直接引用唯一元素的@attributes 数组?

任何帮助将不胜感激:D

4

2 回答 2

0

繁荣!我用下面的代码玩了几个小时,最后把它从编辑器中敲了出来!诀窍是循环使用值作为引用的变量,如果它确实是一个对象,但键不是'@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 回答
0

好吧,您不能拥有一个元素或属性,它是int如此简单地测试数组键0,然后伪造您期望应该工作的数组。

于 2010-01-19T01:47:27.663 回答