问题
I'm using an API that returns XML. I can retrieve one or multiple accounts with the API. I am using the Jms Serializer to deserialize this data into simple model classes that will hold the data.
An account looks like
<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>
I've managed to configure my Account
object as follows, which works fine when deserializing:
<?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
}
Now, when I get multiple accounts in, it looks like this:
<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>
I'd like to deserialize this to an array of accounts. However, at the moment, the only way I've found that does the trick is creating a second Model called Accounts
that looks like this:
<?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
}
When deserializing, I have to pass the correct context:
$serializer->deserialize($rawXml, 'Recurly\Model\Account', 'xml'); // or Recurly\Model\Accounts if I get multiple.
I found somewhere (in a SO question or on the JMS Serializer Github) that you can also pass "types" as context, like $serializer->deserialize($rawXml, 'array<Recurly\Model\Account>', 'xml')
but this just results in an empty array... Anyone know if it's possible to deserialze the array without an extra data model?
回答1:
You can use $serializer->deserialize($rawXml, 'array', 'xml') by adjusting xml structure (result and entry are default values). There is 4th parameter in deserialize - $context it can redefine default values, but i can not find the way how.
<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>
来源:https://stackoverflow.com/questions/20635126/deserializing-xml-array