0

我正在尝试解析这个 XML 结构,但找不到使用递归解析“n”深度嵌套标签的方法。xml结构:

<plist version="1.0">
    <key>1.1.1</key>
    <dict>
        <key>nag</key>
        <integer>1</integer>
    </dict>

    <key>2.2.2</key>
    <dict>
        <key>nag</key>
        <integer>1</integer>
    </dict>

    <key>3.3.3</key>
    <dict>
        <key>show_upgrade_button</key>
        <integer>0</integer>

        <key>nag_startup</key>
        <dict>
            <key>nag_gameover</key>
            <integer>3</integer>
        </dict>

        <key>my_stuff</key>
        <string>1=cb 2=rm 3=cb+rm =leave banner ads off</string>

    </dict>

    <key>4.4.4</key>
    <dict>
        <key>nag</key>
        <integer>1</integer>
    </dict>
</plist>

节点匹配key-dict作为关键节点,节点内部数据的版本号,dict但 xml 结构具有任意dict嵌套,如您在上面的代码中所见。我有这个递归函数,dict到目前为止它接受一个节点,但我看不到光。

<? php
function recursiveNodes($nodes, $arr){
        $count=0;
        if($nodes->hasChildNodes() === true  ){ 

            foreach($nodes->childNodes as $node){

                $temp = array();
                if($node->nodeName === 'key'){

                    $temp['key_name'] = $node->nodeValue;
                    if($node->nextSibling->nodeName !== 'dict'){
                        $sibling = $node->nextSibling;                      
                        $temp['type_name'] = $sibling ->nodeName;
                        $temp['value_name'] = $sibling ->nodeValue;
                    }
                    if($sibling->nodeName === 'dict'){
                    return recursiveNodes($sibling, $arr[$count++][]=$temp);
                }   
                }

            }

        }
            return $arr;
    }
    ?>
4

2 回答 2

1

你的函数中的递归被破坏了。将它包装成一个对象而不是单个函数可能更容易。

这也将允许根据需要更轻松地扩展它。

请参阅以下用法示例:

$parser = new PlistXMLParser();
$parser->loadXML($xml);
print_r($parser->parse());

通过您的示例性输入,它提供以下信息:

Array
(
    [1.1.1] => Array
        (
            [nag] => 1
        )

    [2.2.2] => Array
        (
            [nag] => 1
        )

    [3.3.3] => Array
        (
            [show_upgrade_button] => 0
            [nag_startup] => Array
                (
                    [nag_gameover] => 3
                )

            [my_stuff] => 1=cb 2=rm 3=cb+rm =leave banner ads off
        )

    [4.4.4] => Array
        (
            [nag] => 1
        )

)

在内部,这基本上可以按照您已经做的方式工作,请参见此处的来源摘录:

...
switch ($type) {
    case self::NODE_INTEGER:
        $result[$keyString] = sprintf('%0.0f', trim($value));
        break;

    case self::NODE_STRING:
        $result[$keyString] = (string)$value;
        break;

    case self::NODE_DICT:
        $parser = new self();
        $parser->loadSimpleXMLElement($value);
        $result[$keyString] = $parser->parse();
        break;

    default:
        throw new UnexpectedValueException(sprintf('Unexpected type "%s" for key "%s"', $type, $key));
}
...

解析器正在使用一种switch构造来更好地处理 XML 结构中出现的各个类型标记。异常突出显示您尚未实现的功能,并触发递归NODE_DICT,只需实例化一个新的解析器并让它完成工作。一种非常简单的递归形式。

于 2013-07-05T09:44:14.757 回答
0
//Using SimpleXML library
public function getNodes($root) 
{   
    $output = array();

    if($root->children()) {
        $children = $root->children();   

        foreach($children as $child) {
            if(!($child->children())) {
                $output[] = (array) $child;
            }
            else {
                $output[] = self::getNodes($child->children());
            } 
        }
    }   
    else {
        $output = (array) $root;
    }   

    return $output;
}   
于 2019-04-05T06:00:07.360 回答