是否可以将所有XML数据保存在一维数组中?

时间:2018-08-10 17:30:17

标签: php mysql xml xml-parsing

示例:

<school>
  <students>
    <student idNumber="123" enrollmentNo="E101">
      <name>
        <firstname>Jack</firstname>
        <lastname>Harmor</lastname>
        <standard>7th</standard>
      </name>
    </student>
    <student idNumber="243">
      <name>
        <firstname>Cris</firstname>
        <lastname>Warner</lastname>
        <standard>5th</standard>
      </name>
    </student>
    <student idNumber="345">
      <name>
        <firstname>Rick</firstname>
        <lastname>Corner</lastname>
        <standard>6th</standard>
      </name>
    </student>
  </students>
  <fees type="teaching">
    <fifth>100</fifth>
    <sixth>110</sixth>
    <seventh>120</seventh>
  </fees>
</school>

我想创建一个如下所示的数组

array(
  [students_student_name_firstname0]=>Jack,
  [students_student_name_lastname0]=>Harmor,
  [students_student_name_standard0]=>7th,
  [students_student_name_firstname1]=>Cris,
  [students_student_name_lastname1]=>Warner,
  [students_student_name_standard1]=>5th,
  [students_student_name_firstname2]=>Rick,
  [students_student_name_lastname2]=>Corner,
  [students_student_name_standard2]=>6th,
  [students_fifth0]=>100,
  [students_sixth0]=>110,
  [students_seventh0]=>120,
  [attributes]=>array(
    [student0]=>array(
      [idNumber]=>123,
      [enrollmentNo]=>E101
    ),
    [student1]=>array(
      [idNumber]=>243
    ),
    [student2]=>array(
      [idNumber]=>345
    )
  )
);

上面是一个示例,该类型的XML可以发送以获取数据,但是问题是存在任意数量的XML级别,可能是1,2,3,..,N级别,所以我如何获取其中的所有数据如上所述的一维/二维数组(这意味着数组级别有限),动态存储特定标签的键名和值以及属性名及其值的最简单方法是什么?或者,如果您有更好的方法可以共享,也可以共享。我对此没有更多的了解,请帮助我。 预先感谢。

2 个答案:

答案 0 :(得分:1)

要直接转换为数组,您可以按照自己的意愿在一个循环中进行处理:

$array = json_decode(json_encode(simplexml_load_string($xml)), true);

但是,如果您想尽可能地展平,那么可以做一些额外的事情:

$xml = '
<school>
  <students>
    <student idNumber="123" enrollmentNo="E101">
      <name>
        <firstname>Jack</firstname>
        <lastname>Harmor</lastname>
        <standard>7th</standard>
      </name>
    </student>
    <student idNumber="243">
      <name>
        <firstname>Cris</firstname>
        <lastname>Warner</lastname>
        <standard>5th</standard>
      </name>
    </student>
    <student idNumber="345">
      <name>
        <firstname>Rick</firstname>
        <lastname>Corner</lastname>
        <standard>6th</standard>
      </name>
    </student>
  </students>
  <fees type="teaching">
    <fifth>100</fifth>
    <sixth>110</sixth>
    <seventh>120</seventh>
  </fees>
</school>
';

$array = json_decode(json_encode(simplexml_load_string($xml)), true);

$result = [];
foreach ($array['students']['student'] as $element) {
    $data = [];

    foreach ($element as $elements) {
        foreach ($elements as $k => $v) {
            $data[$k] = $v;
        }
    }

    $result[] = $data;
}

$fees = [];
foreach ($array['fees'] as $k => $v) {
    if ($k == '@attributes') {
        foreach ($v as $attr => $val) {
            $fees[$attr] = $val;
        }
    } else {
        $fees[$k] = $v;
    }
}

$result['fees'] = $fees;

echo '<pre>';
print_r($result);

结果:

Array
(
    [0] => Array
        (
            [idNumber] => 123
            [enrollmentNo] => E101
            [firstname] => Jack
            [lastname] => Harmor
            [standard] => 7th
        )

    [1] => Array
        (
            [idNumber] => 243
            [firstname] => Cris
            [lastname] => Warner
            [standard] => 5th
        )

    [2] => Array
        (
            [idNumber] => 345
            [firstname] => Rick
            [lastname] => Corner
            [standard] => 6th
        )

    [fees] => Array
        (
            [type] => teaching
            [fifth] => 100
            [sixth] => 110
            [seventh] => 120
        )

)

答案 1 :(得分:0)

要能够获取具有值(即,排除任何文档中的普通空格)和所有属性的所有文本节点,可以使用以下代码。请注意,这不会给您与您提供的格式相同的格式,但是格式应允许您提出一些建议。

$xml = new DOMDocument();
$xml->preserveWhiteSpace = false;
$xml->load($file);
$xp = new DOMXPath($xml);
$entries = $xp->query("//node()[not(node())][string-length(normalize-space(.) ) > 1]");
foreach ( $entries as $data )   {
    echo $data->getNodePath()."=".$data->nodeValue.PHP_EOL;
}

echo "Attributes".PHP_EOL;
$attributes = $xp->query("//@*");
foreach ( $attributes as $data )   {
    echo $data->getNodePath()."=".$data->nodeValue.PHP_EOL;
}

给......

/school/students/student[1]/name/firstname/text()=Jack
/school/students/student[1]/name/lastname/text()=Harmor
/school/students/student[1]/name/standard/text()=7th
/school/students/student[2]/name/firstname/text()=Cris
/school/students/student[2]/name/lastname/text()=Warner
/school/students/student[2]/name/standard/text()=5th
/school/students/student[3]/name/firstname/text()=Rick
/school/students/student[3]/name/lastname/text()=Corner
/school/students/student[3]/name/standard/text()=6th
/school/fees/fifth/text()=100
/school/fees/sixth/text()=110
/school/fees/seventh/text()=120
Attributes
/school/students/student[1]/@idNumber=123
/school/students/student[1]/@enrollmentNo=E101
/school/students/student[2]/@idNumber=243
/school/students/student[3]/@idNumber=345
/school/fees/@type=teaching

您可能会希望剪掉姓名的某些部分(即text())等。

尽管坚持按原样处理XML会更好。