Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

serialization - SYMFONY Serializer - Decode XML file in an array, force type of a child element

I have a little problem when I want deserialize a XML File.

These are 2 differents file :

First file :

<allergenRelatedInformation>
    <allergenSpecificationAgency>European Union</allergenSpecificationAgency>
    <allergenSpecificationName>2003/89/EC</allergenSpecificationName>
    <allergenStatement languageCode="fr">Blé</allergenStatement>
    <isAllergenRelevantDataProvided>true</isAllergenRelevantDataProvided>
    <allergen>
       <allergenTypeCode>UW</allergenTypeCode>
       <levelOfContainmentCode>CONTAINS</levelOfContainmentCode>
    </allergen>
 </allergenRelatedInformation>

Second File :

<allergenRelatedInformation>
  <allergenSpecificationAgency>European Union</allergenSpecificationAgency>
  <allergenSpecificationName>2003/89/EC</allergenSpecificationName>
  <allergenStatement languageCode="fr">Arachides</allergenStatement>
  <isAllergenRelevantDataProvided>true</isAllergenRelevantDataProvided>
  <allergen>
     <allergenTypeCode>NP</allergenTypeCode>
     <levelOfContainmentCode>MAY_CONTAIN</levelOfContainmentCode>
  </allergen>
  <allergen>
     <allergenTypeCode>AP</allergenTypeCode>
     <levelOfContainmentCode>CONTAINS</levelOfContainmentCode>
  </allergen>
  <allergen>
     <allergenTypeCode>UW</allergenTypeCode>
     <levelOfContainmentCode>MAY_CONTAIN</levelOfContainmentCode>
  </allergen>
</allergenRelatedInformation>

When I deserialize, I have for the first file :

"allergenRelatedInformation" => array:5 [▼
    "allergenSpecificationAgency" => "European Union"
    "allergenSpecificationName" => "2003/89/EC"
    "allergenStatement" => array:2 [?]
    "isAllergenRelevantDataProvided" => "true"
    "allergen" => array:2 [▼
        "allergenTypeCode" => "UW"
        "levelOfContainmentCode" => "CONTAINS"
]]

Second :

"allergenRelatedInformation" => array:5 [▼
    "allergenSpecificationAgency" => "European Union"
    "allergenSpecificationName" => "2003/89/EC"
    "allergenStatement" => array:2 [?]
    "isAllergenRelevantDataProvided" => "true"
    "allergen" => array:3 [▼
        0 => array:2 [▼
           "allergenTypeCode" => "NP"
           "levelOfContainmentCode" => "MAY_CONTAIN"
        ]
        1 => array:2 [▼
           "allergenTypeCode" => "AP"
           "levelOfContainmentCode" => "CONTAINS"
        ]
        2 => array:2 [▼
           "allergenTypeCode" => "UW"
           "levelOfContainmentCode" => "MAY_CONTAIN"
        ]
]]]

My problem, it's "allergen" array are only one dimension in the first file, and array of array in the second... How I can tell in serializer it's always an array of array ?

I use :

SymfonyComponentSerializerSerializerInterface;

With method :

$this->serializer->deserialize($this->fileXML, ProductSync::class, 'xml');
question from:https://stackoverflow.com/questions/65843677/symfony-serializer-decode-xml-file-in-an-array-force-type-of-a-child-element

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There is no way serializer would know by himself that "allergen" is always multidimensional array.

1. Use as_collection option for Serializer:

$this->serializer->deserialize($this->fileXML, ProductSync::class, 'xml', [
    'as_collection' => true
]);

Result is always consistent, but it deserialize every element as array.

Source: https://symfony.com/doc/current/components/serializer.html#the-csvencoder-context-options

2. Custom transformation:

$allergen = $productSync['allergenRelatedInformation']['allergen'];
if (isset($allergen['allergenTypeCode'])) {
    $productSync['allergenRelatedInformation']['allergen'] = [$allergen];
}

3. Change XML:

<allergenRelatedInformation>
    <allergens>        
        <allergen>
            <allergenTypeCode>NP</allergenTypeCode>
            <levelOfContainmentCode>MAY_CONTAIN</levelOfContainmentCode>
        </allergen>    
        <allergen>
            <allergenTypeCode>UW</allergenTypeCode>
            <levelOfContainmentCode>MAY_CONTAIN</levelOfContainmentCode>
        </allergen>
    </allergens>
</allergenRelatedInformation>

This way serializer know that "allergen" is one element of "allergens" element.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...