Skip to content

[Serializer] XML Collections not correctly hydrated #25227

@Aerendir

Description

@Aerendir
Q A
Bug report? yes
Feature request? no
Symfony version ^3.0

I'm getting responses from a remote API that i decode using Serializer component.

The problem is with a collection: if it contains only one element it isn't added a numeric key.

I explain better.

Example response with more than one element:

        <order_rows nodeType="order_row" virtualEntity="true">
                <order_row>
                    <id>
                        <![CDATA[25]]>
                    </id>
                    <product_id>
                        <![CDATA[4]]>
                    </product_id>
                    <product_attribute_id>
                        <![CDATA[16]]>
                    </product_attribute_id>
                    <product_quantity>
                        <![CDATA[3]]>
                    </product_quantity>
                    <product_name>
                        <![CDATA[Abito stampato - Size : S, Color : Beige]]>
                    </product_name>
                    <product_reference>
                        <![CDATA[demo_4]]>
                    </product_reference>
                    <product_ean13></product_ean13>
                    <product_upc></product_upc>
                    <product_price>
                        <![CDATA[56.980867]]>
                    </product_price>
                    <unit_price_tax_incl>
                        <![CDATA[62.564991]]>
                    </unit_price_tax_incl>
                    <unit_price_tax_excl>
                        <![CDATA[51.282780]]>
                    </unit_price_tax_excl>
                </order_row>
                <order_row>
                    <id>
                        <![CDATA[26]]>
                    </id>
                    <product_id>
                        <![CDATA[4]]>
                    </product_id>
                    <product_attribute_id>
                        <![CDATA[17]]>
                    </product_attribute_id>
                    <product_quantity>
                        <![CDATA[1]]>
                    </product_quantity>
                    <product_name>
                        <![CDATA[Abito stampato - Size : M, Color : Beige]]>
                    </product_name>
                    <product_reference>
                        <![CDATA[demo_4]]>
                    </product_reference>
                    <product_ean13></product_ean13>
                    <product_upc></product_upc>
                    <product_price>
                        <![CDATA[56.980867]]>
                    </product_price>
                    <unit_price_tax_incl>
                        <![CDATA[62.564991]]>
                    </unit_price_tax_incl>
                    <unit_price_tax_excl>
                        <![CDATA[51.282780]]>
                    </unit_price_tax_excl>
                </order_row>
                <order_row>
                    <id>
                        <![CDATA[27]]>
                    </id>
                    <product_id>
                        <![CDATA[1]]>
                    </product_id>
                    <product_attribute_id>
                        <![CDATA[5]]>
                    </product_attribute_id>
                    <product_quantity>
                        <![CDATA[1]]>
                    </product_quantity>
                    <product_name>
                        <![CDATA[T-shirt scolorite a manica corta - Size : L, Color : Arancione]]>
                    </product_name>
                    <product_reference>
                        <![CDATA[demo_1]]>
                    </product_reference>
                    <product_ean13></product_ean13>
                    <product_upc></product_upc>
                    <product_price>
                        <![CDATA[18.448274]]>
                    </product_price>
                    <unit_price_tax_incl>
                        <![CDATA[20.256205]]>
                    </unit_price_tax_incl>
                    <unit_price_tax_excl>
                        <![CDATA[16.603447]]>
                    </unit_price_tax_excl>
                </order_row>
                <order_row>
                    <id>
                        <![CDATA[28]]>
                    </id>
                    <product_id>
                        <![CDATA[1]]>
                    </product_id>
                    <product_attribute_id>
                        <![CDATA[2]]>
                    </product_attribute_id>
                    <product_quantity>
                        <![CDATA[2]]>
                    </product_quantity>
                    <product_name>
                        <![CDATA[T-shirt scolorite a manica corta - Size : S, Color : Blu]]>
                    </product_name>
                    <product_reference>
                        <![CDATA[demo_1]]>
                    </product_reference>
                    <product_ean13></product_ean13>
                    <product_upc></product_upc>
                    <product_price>
                        <![CDATA[18.448274]]>
                    </product_price>
                    <unit_price_tax_incl>
                        <![CDATA[20.256205]]>
                    </unit_price_tax_incl>
                    <unit_price_tax_excl>
                        <![CDATA[16.603447]]>
                    </unit_price_tax_excl>
                </order_row>
            </order_rows>

This is transformed into an array like this:

"order_rows" => array:3 [▼
          "@nodeType" => "order_row"
          "@virtualEntity" => "true"
          "order_row" => array:4 [▼
            0 => array:11 [▼
              "id" => "25"
              "product_id" => "4"
              "product_attribute_id" => "16"
              "product_quantity" => "3"
              "product_name" => "Abito stampato - Size : S, Color : Beige"
              "product_reference" => "demo_4"
              "product_ean13" => ""
              "product_upc" => ""
              "product_price" => "56.980867"
              "unit_price_tax_incl" => "62.564991"
              "unit_price_tax_excl" => "51.282780"
            ]
            1 => array:11 [▶]
            2 => array:11 [▶]
            3 => array:11 [▶]
          ]
        ]

But if the collection contains only one element like in this response:

        <order_rows nodeType="order_row" virtualEntity="true">
                <order_row>
                    <id>
                        <![CDATA[16]]>
                    </id>
                    <product_id>
                        <![CDATA[1]]>
                    </product_id>
                    <product_attribute_id>
                        <![CDATA[1]]>
                    </product_attribute_id>
                    <product_quantity>
                        <![CDATA[1]]>
                    </product_quantity>
                    <product_name>
                        <![CDATA[T-shirt scolorite a manica corta - Size : S, Color : Arancione]]>
                    </product_name>
                    <product_reference>
                        <![CDATA[demo_1]]>
                    </product_reference>
                    <product_ean13></product_ean13>
                    <product_upc></product_upc>
                    <product_price>
                        <![CDATA[18.448274]]>
                    </product_price>
                    <unit_price_tax_incl>
                        <![CDATA[22.506894]]>
                    </unit_price_tax_incl>
                    <unit_price_tax_excl>
                        <![CDATA[18.448274]]>
                    </unit_price_tax_excl>
                </order_row>
            </order_rows>

The resulting array is this:

        "order_rows" => array:3 [▼
                  "@nodeType" => "order_row"
                  "@virtualEntity" => "true"
                  "order_row" => array:11 [▼
                    "id" => "16"
                    "product_id" => "1"
                    "product_attribute_id" => "1"
                    "product_quantity" => "1"
                    "product_name" => "T-shirt scolorite a manica corta - Size : S, Color : Arancione"
                    "product_reference" => "demo_1"
                    "product_ean13" => ""
                    "product_upc" => ""
                    "product_price" => "18.448274"
                    "unit_price_tax_incl" => "22.506894"
                    "unit_price_tax_excl" => "18.448274"
                  ]
                ]

So, if I have more than one order_row I can do something like this:

foreach ($response['order_rows']['order_row'] as $row) {
    // Here $row will contain keys like id, product_id, ecc.
}

But if I have only one order_row, then the previous foreach breaks as I don't get an array with only 1 order_row but I get directly the id, the product_id, ecc.

Is something that I'm doing wrong, or there is a problem with the Serializer?

EDIT

I'm not doing something wrong: this is an intended (wrong) behavior.

The same problem happens in other serializers: see #21616

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions