2

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>[email protected]</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?

2
  • There are different Namspaces * @JMS\Type("array<Recurly\Model\Account>") and here deserialize($rawXml, 'array<Model\Account>) is this correct? Commented Dec 17, 2013 at 13:29
  • Yeah, that's just from typing and copy/pasting. If the namespaces were incorrect, it'd be getting exceptions. I've corrected and clarified the namespaces. Commented Dec 17, 2013 at 13:33

1 Answer 1

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>[email protected]</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>[email protected]</email>
        <first_name>Verena</first_name>
        <last_name>Example</last_name>
    </entry>
</result>
Sign up to request clarification or add additional context in comments.

2 Comments

The XML is coming from an API I have no control over. I cannot adjust the structure.
JMS deserializer really sucks in this

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.