Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserialization of collection when wraped by aditional xml tags #719

Closed
jantajov opened this issue Mar 2, 2017 · 3 comments
Closed

Deserialization of collection when wraped by aditional xml tags #719

jantajov opened this issue Mar 2, 2017 · 3 comments

Comments

@jantajov
Copy link

jantajov commented Mar 2, 2017

Greetings I am currently trying to figure out how can I deserialize XML collection when there is an additional tag in my way.

I have following XML:

<?xml version="1.0"?>
<countries>
    <items>
        <country>
            <continentGeoId>6255147</continentGeoId>
            <countryCode>AF</countryCode>
            <countryGeoId>1149361</countryGeoId>
            <name>Afghanistan</name>
        </country>
        <country>
            <continentGeoId>6255148</continentGeoId>
            <countryCode>AX</countryCode>
            <countryGeoId>661882</countryGeoId>
            <name>Aland Islands</name>
        </country>
        <country>
            <continentGeoId>6255148</continentGeoId>
            <countryCode>AL</countryCode>
            <countryGeoId>783754</countryGeoId>
            <name>Albania</name>
        </country>
    </items>
</countries>

and this is my class:

/**
 * Class Country
 * @XmlRoot("country")
 * @ExclusionPolicy("none")
 */
class Country {

    /**
     * @var integer Country GEO identifier.
     * @Type("integer")
     * @SerializedName("countryGeoId")
     */
    private $countryGeoId;
    /**
     * @var string Country name.
     * @Type("string")
     * @SerializedName("name")
     */
    private $name;
    /**
     * @var string 2-letter country code.
     * @Type("string")
     * @SerializedName("countryCode")
     */
    private $countryCode;
    /**
     * @var integer GEO identifier of continent.
     * @Type("integer")
     * @SerializedName("continentGeoId")
     */
    private $continentGeoId;

    /**
     * @return int
     */
    public function getCountryGeoId() {
        return $this->countryGeoId;
    }
    /**
     * @param int $countryGeoId
     */
    public function setCountryGeoId($countryGeoId) {
        $this->countryGeoId = $countryGeoId;
    }

    /**
     * @return string
     */
    public function getName() {
        return $this->name;
    }
    /**
     * @param string $name
     */
    public function setName($name) {
        $this->name = $name;
    }

    /**
     * @return string
     */
    public function getCountryCode() {
        return $this->countryCode;
    }
    /**
     * @param string $countryCode
     */
    public function setCountryCode($countryCode) {
        $this->countryCode = $countryCode;
    }

    /**
     * @return int
     */
    public function getContinentGeoId() {
        return $this->continentGeoId;
    }
    /**
     * @param int $continentGeoId
     */
    public function setContinentGeoId($continentGeoId) {
        $this->continentGeoId = $continentGeoId;
    }

}

Then I tried:

$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$collection = $serializer->deserialize($xml, 'ArrayCollection<' . Country::class . '>', 'xml');
@goetas
Copy link
Collaborator

goetas commented Mar 6, 2017

you need a custom deserializer to handle it,

$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$collection = $serializer->deserialize($xml, 'MyNestedCollection<' . Country::class . '>', 'xml');

Now you can add a handler for the virtual type MyNestedCollection and inside it, get the items element and perform a "visitArray" (or $navigator->accept())

@jantajov
Copy link
Author

jantajov commented Mar 6, 2017

Actually, I have solved it by introducing wrapper class CountryCollection

/**
 * Class CountryCollection
 * @XmlRoot("countries")
 */
class CountryCollection {

    /**
     * @var Country[]
     * @Type("array<Country>")
     * @XmlList(entry="country")
     * @SerializedName("items")
     */
    private $items;

// ... etc
}

@goetas
Copy link
Collaborator

goetas commented Mar 6, 2017

it works too... but with a custom deserializer, your model stays "clean"

@goetas goetas closed this as completed Mar 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants