【问题标题】:Is it possible to get all XML data in single dimensional array?是否可以在一维数组中获取所有 XML 数据?
【发布时间】:2018-08-10 17:30:16
【问题描述】:

例子:

<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,所以我怎样才能获取所有数据如上所述的单/二维数组(这意味着数组的有限级别)以及动态存储其键名称和值以及属性名称及其特定标签的值的最简单方法是什么?或者,如果您有更好的方法来做到这一点,那么您也可以分享。我对此一无所知,所以请帮助我。 提前致谢。

【问题讨论】:

  • 您预期的输出数组是该格式的要求,还是您只是想将 xml 组织成一个可访问的数组,以便将其发送到任何地方进行处理?
  • 使用这样的平面数组似乎麻烦多于其价值。我推荐$array = json_decode( json_encode( simplexml_load_string( $xml_string ) ), true );,这样您就可以自信地进行迭代、排序等……而无需执行子字符串检查。
  • 是的 dmotors 我只是想将它组织成易于访问的数组。
  • MonkeyZeus 它返回给我 DOMElement Object ( )
  • 不,它没有。你是如何得到你的 XML 字符串的?

标签: php mysql xml xml-parsing


【解决方案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
        )

)

【讨论】:

    【解决方案2】:

    为了能够获取具有 in 值的所有文本节点(即排除任何文档中的正常空白)和所有属性,您可以使用以下代码。请注意,这不会为您提供与您提供的相同格式,但该格式应该允许您在之后想出一些东西..

    $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 会更好。

    【讨论】:

    • 非常感谢 Nigel Ren,它对我很有用,现在我将这个键存储到我的表中,当我需要获取特定值时,我将从这个数组中搜索值。但问题是,在表中我存储的是固定值,而 XML 可能是动态的/school/students/student[1]/name/firstname/text() 表示已添加 [1] 那么如何使用此键从数组中获取值?
    猜你喜欢
    • 2011-12-16
    • 2021-11-16
    • 2013-08-06
    • 1970-01-01
    • 2015-08-31
    • 2014-09-28
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    相关资源
    最近更新 更多