使用SimpleXML反序列化XML数组

时间:2013-12-18 10:42:25

标签: php simplexml

我需要将我收到的一些XML反序列化为一个对象。我使用SimpleXML来做到这一点。收到的一些XML的一个例子是:

<?xml version="1.0" encoding="UTF-8"?>
<coupons type="array">
  <coupon>
    <coupon_code>baz</coupon_code>
    <name>baz</name>
    <discount_type>percent</discount_type>
    <discount_percent type="integer">20</discount_percent>
    <plan_codes type="array">
      <plan_code>plus</plan_code>
      <plan_code>pro</plan_code>
    </plan_codes>
  </coupon>
  <coupon>
    <coupon_code>test</coupon_code>
    <name>Test</name>
    <discount_type>dollars</discount_type>
    <discount_in_cents>
      <USD type="integer">2000</USD>
      <EUR type="integer">1500</USD>
    </discount_in_cents>
    <plan_codes type="array">
      <plan_code>plus</plan_code>
    </plan_codes>
  </coupon>
</coupons>

在这段XML中,有3种类型的数组:<coupons><coupon>的数组。 <coupon>也有2个数组:<plan_codes>(这是一个平面数组)和<discount_in_cents>是一个关联数组。

我的反序列化器如何工作:我从XML创建一个SimpleXMLElement并将其传递给一个函数visitElement,它接受​​一个SimpleXMLElement,在这种情况下类型为array<Model\Coupon>,表明它是一个{的数组{1}}对象。

在我的Model\Coupon中,我检查类型是否是现有类,如果是,我创建该类的新实例并获取该模型的配置,配置告诉我哪些子项需要反序列化为哪个对象变量。 visitElement看起来像这样:

visitElement

这样,我有一个很好的递归方式来反序列化其他XML,它可能有嵌套对象(例如,Account XML有一个嵌套在其中的Address对象)。

我的public function visitElement($element, $type) { // it is possible the element is not available if (!$element) { return null; } else { // get the value based on it's mapped type switch ($type) { case 'string': return $this->visitString($element); break; // ... // other cases // ... default: // catch other cases if (class_exists($type)) { // We mapped to an existing class return $this->visitModel($type, $element); } elseif ($this->isArrayType($type, $arrayType, $keepKey)) { // We mapped to an array<type> return $this->visitArray($arrayType, $element, $keepKey); } else { // A type we can't handle return null; } } } } 已配置为Model\Coupon<plan_codes>分别被视为<discount_in_cents>array<string>

这是我的array<integer>功能:

visitArray

这一切都很美妙。我得到一个包含2个protected function visitArray($type, $element, $keepKey = false) { $value = null; $i = 0; foreach ($element->children() as $key => $child) { $k = $keepKey ? $key : $i++; $value[$k] = $this->visitElement($child, $type); } return $value; } 个对象的数组,第二个对象有一个看起来像['USD'=&gt;的discount_in_cents数组。 2000年,'EUR'=&gt; 1500],但它不适用于计划代码...

当我var_dump那些,我得到

Model\Coupon

array (size=2)
  0 => null
  1 => null

是否有任何理由为什么循环array (size=1) 0 => null 会产生与<plan_codes><coupons>不同的结果/子女?

目前,我在<discount_in_cents>中实施了一种解决方法,如下所示:

visitArray

0 个答案:

没有答案