防止SimpleXML合并重复的元素/标签?

时间:2014-09-23 01:51:52

标签: php arrays xml dom simplexml

我有一些来自avendor的非标准XML,带有重复元素。

SimpleXML和DOM都在合并我的XML标签。我怎么能阻止这个?

有没有办法让它们在没有它们合并的情况下进入数组?

我的XML是这样的:

<quiz> <settings> <user name="joe" email="blah@blah.com" /> </settings> <questions> <multiplechoice id="1"> <directions>What is 1+1?</directions> <answer correct="true" selected="false">2</answer> <answer correct="false" selected="false">4</answer> <answer correct="false" selected="true">1</answer> <answer correct="false" selected="false">0</answer> </multiplechoice> <truefalse id="2"> <directions>0 > 1?</directions> <answer correct="true" selected="false">True</answer> <answer correct="false" selected="true">False</answer> </truefalse> <multiplechoice id="3"> <directions>What is 2+1?</directions> <answer correct="true" selected="false">3</answer> <answer correct="false" selected="false">4</answer> <answer correct="false" selected="true">1</answer> <answer correct="false" selected="false">0</answer> </multiplechoice> </questions> </quiz>

我的PHP是这样的:

$xml = new SimpleXMLElement($xmldata);

发生了什么事?

无论我如何尝试,SimpleXML都会将<multiplechoice>元素合并为一个array(),如下所示:

[questions] => Array
(
    [multiplechoice] => Array
        (
            [0] => Array
                (
                    [@attributes] => Array
                        (
                            [id] => 1}
                        )
                    [directions] => What is 1+1?
                    [answers] => Array
                        (
                            [answer] => Array
                                (
                                    [0] => 2
                                    [1] => 4
                                    [2] => 1
                                    [3] => 0
                                )

                        )

                )

            [1] => Array
                (
                    [@attributes] => Array
                        (
                            [id] => 3
                        )
                   [directions] => What is 2+1?
                    [answers] => Array
                        (
                            [answer] => Array
                                (
                                    [0] => 3
                                    [1] => 4
                                    [2] => 1
                                    [3] => 0
                                )

                        )

                )
        )
    [truefalse] => Array
        (
            [0] => Array
                (
                    [@attributes] => Array
                        (
                            [id] => 2}
                        )

                    [directions] => 0 > 1?
                    [answers] => Array
                        (
                            [answer] => Array
                                (
                                    [0] => True
                                    [1] => False
                                )
                        )
                )
        )
)

我想要的是什么:

<multiplechoice>元素应该按照初始顺序分开:

[questions] => Array
(
    [multiplechoice] => Array
        (
            [0] => Array
                (
                    [@attributes] => Array
                        (
                            [id] => 1}
                        )
                    [directions] => What is 1+1?
                    [answers] => Array
                        (
                            [answer] => Array
                                (
                                    [0] => 2
                                    [1] => 4
                                    [2] => 1
                                    [3] => 0
                                )

                        )

                )
        )
    [truefalse] => Array
        (
            [0] => Array
                (
                    [@attributes] => Array
                        (
                            [id] => 2}
                        )

                    [directions] => 0 > 1?
                    [answers] => Array
                        (
                            [answer] => Array
                                (
                                    [0] => True
                                    [1] => False
                                )
                        )
                )
        )
   [multiplechoice] => Array
        (
            [0] => Array
                (
                    [@attributes] => Array
                        (
                            [id] => 3
                        )
                   [directions] => What is 2+1?
                    [answers] => Array
                        (
                            [answer] => Array
                                (
                                    [0] => 3
                                    [1] => 4
                                    [2] => 1
                                    [3] => 0
                                )

                        )

                )
        )        
)

2 个答案:

答案 0 :(得分:1)

我不知道你使用DOM做了什么,但它在这里保持开箱即用的顺序:

$dom = new DOMDocument();
$dom->loadXML($xml);
$questions = $dom->getElementsByTagName('questions')->item(0);
if($questions instanceof DOMElement){
        foreach($questions->childNodes as $child){
                if($child instanceof DOMElement){
                        var_dump($child->tagName, simplexml_import_dom($child));
                }
        }
}

完美的顺序:

string(14) "multiplechoice"
class SimpleXMLElement#4 (3) {
  public $@attributes =>
  array(1) {
    'id' =>
    string(1) "1"
  }
  public $directions =>
  string(12) "What is 1+1?"
  public $answer =>
  array(4) {
    [0] =>
    string(1) "2"
    [1] =>
    string(1) "4"
    [2] =>
    string(1) "1"
    [3] =>
    string(1) "0"
  }
}
string(9) "truefalse"
class SimpleXMLElement#4 (3) {
  public $@attributes =>
  array(1) {
    'id' =>
    string(1) "2"
  }
  public $directions =>
  string(6) "0 > 1?"
  public $answer =>
  array(2) {
    [0] =>
    string(4) "True"
    [1] =>
    string(5) "False"
  }
}
string(14) "multiplechoice"
class SimpleXMLElement#4 (3) {
  public $@attributes =>
  array(1) {
    'id' =>
    string(1) "3"
  }
  public $directions =>
  string(12) "What is 2+1?"
  public $answer =>
  array(4) {
    [0] =>
    string(1) "3"
    [1] =>
    string(1) "4"
    [2] =>
    string(1) "1"
    [3] =>
    string(1) "0"
  }

答案 1 :(得分:0)

与其他人一样。我自己已经概述过,不可能按照你在问题中要求的方式将树结构放入数组中。

XML是一种树结构,具有相同名称的多个元素可以存在于同一级别上。数组无法实现的东西。

所以最好保持 SimpleXMLElement 不变。对数据进行操作比处理数组要舒服得多。

然而据说,仍然可以使用类似于你要求的数据创建一个阵列,但它需要对其中的结构进行特殊处理。没有通用的方法来处理它。

例如:所有来自问题的子元素,然后用他们的名字键入:

$result = $xml->xpath('//questions/*');

foreach ($result as &$rebuild) {
    $rebuild = [$rebuild->getName() => $rebuild];
}
unset($rebuild);
$result = ['questions' => $result];

$array  = json_decode(json_encode($result), true);

然后生成的数组采用这种格式,我觉得处理起来不太实用:

Array
(
    [questions] => Array
        (
            [0] => Array
                (
                    [multiplechoice] => Array
                        (
                            [@attributes] => Array
                                (
                                    [id] => 1
                                )

                            [directions] => What is 1+1?
                            [answer] => Array
                                (
                                    [0] => 2
                                    [1] => 4
                                    [2] => 1
                                    [3] => 0
                                )

                        )

                )

            [1] => Array
                (
                    [truefalse] => Array
                        (
                            [@attributes] => Array
                                (
                                    [id] => 2
                                )

                            [directions] => 0 > 1?
                            [answer] => Array
                                (
                                    [0] => True
                                    [1] => False
                                )

                        )

                )

            [2] => Array
                (
                    [multiplechoice] => Array
                        (
                            [@attributes] => Array
                                (
                                    [id] => 3
                                )

                            [directions] => What is 2+1?
                            [answer] => Array
                                (
                                    [0] => 3
                                    [1] => 4
                                    [2] => 1
                                    [3] => 0
                                )

                        )

                )

        )

)