使用PHP循环XML simplexml_load_string()

时间:2017-09-19 15:22:39

标签: php xml

所以我连接到api并返回XML。

$vehicles = array();

$xml = simplexml_load_string($result);
foreach($xml->Result as $item)
{
   $vehicle = array();

   foreach($item as $key => $value)
   {
        $vehicle[(string)$key] = (string)$value;
   }

   $vehicles[] = $vehicle;
}

print_r($vehicles);

如果我在var_dump($ result)中显示(在源代码中):

 string(52055) "<?xml version="1.0" encoding="utf-8"?>
<DataTable xmlns="http://tempuri.org/">
  <xs:schema id="DataSet" 
targetNamespace="http://tempuri.org/DataSet.xsd" 
xmlns:mstns="http://tempuri.org/DataSet.xsd" 
xmlns="http://tempuri.org/DataSet.xsd" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:element name="DataSet" msdata:IsDataSet="true" msdata:MainDataTable="http_x003A__x002F__x002F_tempuri.org_x002F_DataSet.xsd_x003A_Result" msdata:UseCurrentLocale="true">
  <xs:complexType>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="Result">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="newUsed" type="xs:string" minOccurs="0" />
            <xs:element name="unitNumber" type="xs:string" minOccurs="0" />
            <xs:element name="SN" type="xs:string" minOccurs="0" />
            <xs:element name="Make" type="xs:string" minOccurs="0" />
            <xs:element name="Model" type="xs:string" minOccurs="0" />
            <xs:element name="mYear" type="xs:string" minOccurs="0" />
            <xs:element name="availability" type="xs:string" minOccurs="0" />

          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:choice>
  </xs:complexType>
 </xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<DataSet xmlns="http://tempuri.org/DataSet.xsd">
  <Result diffgr:id="Result1" msdata:rowOrder="0">
    <newUsed>Used</newUsed>
    <unitNumber>3621P</unitNumber>
    <SN>1M2AG11C94M013645</SN>
    <Make>Mack</Make>
    <Model>CV713</Model>
    <mYear>2004</mYear>
    <availability>In Stock</availability>
      </Result>
    </DataSet>
  </diffgr:diffgram>
</DataTable>"

我的问题是,为什么这会返回一个空数组?我错过了什么?注意:我已经删除了大量的xml以便于阅读。

2 个答案:

答案 0 :(得分:1)

$ xml是xml的根元素,因此它的DataTable。在DataTable和Result之间,层次结构中有一个名为DataSet的节点。

所以你的代码应该是

foreach($xml->DataSet->Result as $item)
{
   ...
}

这是一个例子,你必须在访问他的孩子之前测试$ xml-&gt; DataSet是否存在。

答案 1 :(得分:1)

由于XML文档中的命名空间(其中包含:的元素),您遇到了问题。您无法使用标准-> SimpleXML运算符访问不同命名空间中的子元素 - 您需要使用children()方法循环它们,或使用Xpath访问它们。我更喜欢后者,尽管取决于文档的结构可能是不可能的。

$xml = simplexml_load_string($result);
$xml->registerXPathNamespace("DataSet", "http://tempuri.org/DataSet.xsd");

foreach($xml->xpath('//DataSet:Result') as $item) {
  $vehicle = array();

  foreach($item->children() as $value) {
    $vehicle[$value->getName()] = (string) $value;
  }

  $vehicles[] = $vehicle;
}

print_r($vehicles);

我还更改了您访问<Result>元素子元素的方式 - 您无法使用foreach循环来访问元素作为键/值对。我已通过调用getName替换了标记名称,并将其转换为元素内容的字符串。

有关完整示例,请参阅https://eval.in/864475