我正在尝试解析此XML结构,但无法找到使用递归解析“n”-deep嵌套标记的方法。 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结构具有arbrittrary 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;
}
?>
答案 0 :(得分: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
)
)
在内部,这基本上与你已经如何工作有关,请看这里摘自the sources:
...
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
触发了递归,它只是实例化一个新的解析器并让它完成工作。一种非常简单的递归形式。
答案 1 :(得分: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;
}