PHP迭代XML

时间:2015-09-21 19:07:00

标签: php xml xpath

如何将XML转换为可以迭代的数组。

以下是我的XML

示例
<user>
    <student>yes</student>
    <id>1</id>
    <name>John</name>
</user>

<user>
    <student>yes</student>
    <id>1</id>
    <name>Billy</name>
</user>

我的php看起来像这样

$tmpTemplates = new XDomDocument();
$tmpTemplates->load('.....myFile.xml');
$xPath = new DomXPath($tmpTemplates);
$query = "//user[student='yes']";
$tmpTemplate = $xPath->query($query);

我希望能够做的是

foreach($tmpTemplate as $tt){
    var_dump($tt->student);
    var_dump($tt->id);
    var_dump($tt->name);
}

现在我只能打印出nodeValue,它给我这样的东西:

  是的

     

1

     

约翰

如何将其设为数组或对象,以便我可以通过其键来评估每个值?

4 个答案:

答案 0 :(得分:1)

您在示例中为两个记录使用了相同的ID,因此我更改了第一个记录的id并添加了一个文档元素。

<users>
  <user>
    <student>yes</student>
    <id>2</id>
    <name>John</name>
  </user>
  <user>
    <student>yes</student>
    <id>1</id>
     <name>Billy</name>
  </user>
</users>

使用DOMXpath:evaluate()获取详细信息,第二个参数是表达式的上下文节点。

$document = new DOMDocument();
$document->loadXml($xmlString);
$xPath = new DomXPath($document);

$students = [];
foreach ($xPath->evaluate("//user[student='yes']") as $student) {
  $id = $xPath->evaluate('string(id)', $student);
  $students[$id] = [
    'id' => $id,
    'name' => $xPath->evaluate('string(name)', $student)
  ];
}

var_dump($students);

输出:

array(2) {
  [2]=>
  array(2) {
    ["id"]=>
    string(1) "2"
    ["name"]=>
    string(4) "John"
  }
  [1]=>
  array(2) {
    ["id"]=>
    string(1) "1"
    ["name"]=>
    string(5) "Billy"
  }
}

返回值取决于表达式。像//user[student='yes']name这样的位置路径会返回DOMNodeList。但是您可以直接在Xpath中强制转换节点列表。 string(name)将返回第一个name子节点的内容或空字符串。

答案 1 :(得分:1)

  

如何将其设为数组或对象,以便我可以通过其键来评估每个值?

为了澄清,到目前为止,您已经有了一个对象,它是SimpleXMLElement,您正在使用$tt变量来访问它:

...
    var_dump($tt->student);
    var_dump($tt->id);
    var_dump($tt->name);
...

现在$tt变量来自另一个变量,即迭代它,另一个变量名为$tmpTemplate

...
foreach ($tmpTemplate as $tt) {
    var_dump($tt->student);
    ...

顺便说一下这个变量是一个数组。因此,您可以使用索引(从零开始)来访问它,以便在文档顺序中访问包含<user>子元素的每个<student>元素,其值为“student(为你制定了xpath):

  • $tmpTemplate[0]包含第一个用户 SimpleXMLElement
  • $tmpTemplate[1]包含第二个用户 SimpleXMLElement
  • ......依此类推。

我希望这会让这更加明显。

答案 2 :(得分:0)

尝试使用this php functio n

 xml_parse_into_struct

来自php手册的样本

<?php
  $simple = "<para><note>simple note</note></para>";
  $p = xml_parser_create();
  xml_parse_into_struct($p, $simple, $vals, $index);
  xml_parser_free($p);
  echo "Index array\n";
  print_r($index);
  echo "\nVals array\n";
  print_r($vals);
?>

答案 3 :(得分:0)

您可以使用simplexml_load_file将xml转换为对象。

例如:

$users = simplexml_load_file("users.xml");
foreach($users as $user) {
   ...
}