反序列化XML数组

时间:2013-12-17 13:12:35

标签: php xml symfony jmsserializerbundle

我正在使用返回XML的API。我可以使用API​​检索一个或多个帐户。我正在使用Jms Serializer将此数据反序列化为将保存数据的简单模型类。

帐户看起来像

<account href="https://your-subdomain.recurly.com/v2/accounts/1">
  ...
  <account_code>1</account_code>
  <state>active</state>
  <username nil="nil"></username>
  <email>verena@example.com</email>
  <first_name>Verena</first_name>
  <last_name>Example</last_name>
  ...
  <address>...</address>
</account>

我设法按如下方式配置我的Account对象,这在反序列化时工作正常:

<?php
namespace Recurly\Model;
use JMS\Serializer\Annotation as JMS;

/**
* @JMS\XmlRoot("account")
*/
class Account
{
    /** @JMS\Type("string") */
    protected $account_code;
    /**  @JMS\Type("string") */
    protected $state;
    /** @JMS\Type("string") */
    protected $username;
    /** @JMS\Type("string") */
    protected $email;
    /** @JMS\Type("string") */
    protected $first_name;
    /** @JMS\Type("string") */
    protected $last_name;
    /** @JMS\Type("string") */
    protected $company_name;
    /** @JMS\Type("string") */
    protected $vat_number;
    /** @JMS\Type("Model\Address") */
    protected $address;
    /** @JMS\Type("string") */
    protected $accept_language;
    /** @JMS\Type("string") */
    protected $hosted_login_token;
    /** @JMS\Type("DateTime") */
    protected $created_at;

    // getters and setters here
}

现在,当我收到多个帐户时,它看起来像这样:

<accounts type="array">
  <account href="https://your-subdomain.recurly.com/v2/accounts/1">...</account>
  <account href="https://your-subdomain.recurly.com/v2/accounts/2">...</account>
  <account href="https://your-subdomain.recurly.com/v2/accounts/3">...</account>
</accounts>

我想将其反序列化为一系列帐户。但是,目前,我发现的唯一方法是创建第二个名为Accounts的模型,如下所示:

<?php
namespace Recurly\Model;
use JMS\Serializer\Annotation as JMS;

class Accounts 
{
    /**
     * @var Account[]
     *
     * @JMS\Type("array<Recurly\Model\Account>")
     * @JMS\XmlList(entry="account")
     */
    protected $accounts;

    // getters and setters here
}

反序列化时,我必须传递正确的上下文:

$serializer->deserialize($rawXml, 'Recurly\Model\Account', 'xml'); // or Recurly\Model\Accounts if I get multiple.

我发现某处(在SO问题或JMS Serializer Github上)你也可以将“类型”作为上下文传递,例如$serializer->deserialize($rawXml, 'array<Recurly\Model\Account>', 'xml'),但这只会产生一个空数组...任何人都知道它是否是可以在没有额外数据模型的情况下反序列化数组?

1 个答案:

答案 0 :(得分:1)

您可以通过调整xml结构来使用$ serializer-&gt;反序列化($ rawXml,'array','xml')(结果和条目是默认值)。反序列化中有第4个参数 - $ context它可以重新定义默认值,但我无法找到方法。

<result>
    <entry>
        <account_code>1</account_code>
        <state>active</state>
        <username nil="nil"></username>
        <email>verena@exampl.com</email>
        <first_name>Verena</first_name>
        <last_name>Example</last_name>
    </entry>
    <entry>
        <account_code>1</account_code>
        <state>active</state>
        <username nil="nil"></username>
        <email>verena@exampl.com</email>
        <first_name>Verena</first_name>
        <last_name>Example</last_name>
    </entry>
</result>