xsd2php
xsd2php copied to clipboard
xml_list deserialization does not work
Hi,
This yml metadata was generated:
Mobile\Search\SearchResult:
xml_root_name: search-result
xml_root_namespace: 'http://services.mobile.de/schema/search'
properties:
total:
expose: true
access_type: public_method
serialized_name: total
xml_element:
namespace: 'http://services.mobile.de/schema/search'
accessor:
getter: getTotal
setter: setTotal
type: integer
pageSize:
expose: true
access_type: public_method
serialized_name: page-size
xml_element:
namespace: 'http://services.mobile.de/schema/search'
accessor:
getter: getPageSize
setter: setPageSize
type: integer
currentPage:
expose: true
access_type: public_method
serialized_name: current-page
xml_element:
namespace: 'http://services.mobile.de/schema/search'
accessor:
getter: getCurrentPage
setter: setCurrentPage
type: integer
maxPages:
expose: true
access_type: public_method
serialized_name: max-pages
xml_element:
namespace: 'http://services.mobile.de/schema/search'
accessor:
getter: getMaxPages
setter: setMaxPages
type: integer
errors:
expose: true
access_type: public_method
serialized_name: errors
xml_element:
namespace: 'http://services.mobile.de/schema/common/error-1.0'
accessor:
getter: getErrors
setter: setErrors
type: array<Mobile\Common\Error\Error>
xml_list:
inline: false
entry_name: error
namespace: 'http://services.mobile.de/schema/search'
ads:
expose: true
access_type: public_method
serialized_name: ads
xml_element:
namespace: 'http://services.mobile.de/schema/search'
accessor:
getter: getAds
setter: setAds
type: array<Mobile\Ad\Ad>
xml_list:
inline: false
entry_name: ad
namespace: 'http://services.mobile.de/schema/search'
I've created the serializer with required handlers:
<?php declare(strict_types = 1);
namespace Mobile\Serializer;
use GoetasWebservices\Xsd\XsdToPhpRuntime\Jms\Handler\BaseTypesHandler;
use GoetasWebservices\Xsd\XsdToPhpRuntime\Jms\Handler\XmlSchemaDateHandler;
use JMS\Serializer\Handler\HandlerRegistry;
use JMS\Serializer\Serializer;
use JMS\Serializer\SerializerBuilder;
class SerializerFactory
{
private $metaDataDirectory;
private $prefix;
public function __construct(string $metaDataDirectory, string $prefix)
{
$this->metaDataDirectory = $metaDataDirectory;
$this->prefix = $prefix;
}
public function create(): Serializer
{
$serializerBuilder = SerializerBuilder::create();
return $serializerBuilder
->configureHandlers(function (HandlerRegistry $handlerRegistry) use ($serializerBuilder) {
$serializerBuilder->addDefaultHandlers();
$handlerRegistry->registerSubscribingHandler(new BaseTypesHandler());
$handlerRegistry->registerSubscribingHandler(new XmlSchemaDateHandler());
})
->addMetadataDir(
__DIR__.'/../Resources/'.$this->metaDataDirectory, $this->prefix
)
->build()
;
}
}
xsdconfig:
xsd2php:
namespaces:
'http://services.mobile.de/schema/search': 'Mobile\Search'
'http://services.mobile.de/schema/ad': 'Mobile\Ad'
'http://services.mobile.de/schema/resource': 'Mobile\Resource'
'http://services.mobile.de/schema/seller': 'Mobile\Seller'
'http://services.mobile.de/schema/common/financing-1.0': 'Mobile\Common\Financing'
'http://services.mobile.de/schema/common/error-1.0': 'Mobile\Common\Error'
destinations_php:
'Mobile\Search': Search
'Mobile\Ad': Ad
'Mobile\Resource': Resource
'Mobile\Seller': Seller
'Mobile\Common\Financing': Common\Financing
'Mobile\Common\Error': Common\Error
destinations_jms:
'Mobile': Resources/serializer
aliases:
'http://services.mobile.de/schema/ad':
class: 'Mobile\Ad\Clazz'
'http://services.mobile.de/schema/seller':
value: 'string'
naming_strategy: short
path_generator: psr4
If I try to deserialize this response:
I want to deserialize following xml response:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<search:search-result xmlns:seller="http://services.mobile.de/schema/seller"
xmlns:ad="http://services.mobile.de/schema/ad"
xmlns:search="http://services.mobile.de/schema/search"
xmlns:financing="http://services.mobile.de/schema/common/financing-1.0"
xmlns:resource="http://services.mobile.de/schema/resource"
xmlns:error="http://services.mobile.de/schema/common/error-1.0">
<search:total>14825</search:total>
<search:page-size>20</search:page-size>
<search:current-page>1</search:current-page>
<search:max-pages>742</search:max-pages>
<search:ads>
<ad:ad key="3" url="https://services.mobile.de/search-api/ad/3">
<ad:creation-date value="2015-12-21T15:47:26+01:00"/>
<ad:modification-date value="2017-01-13T16:15:10+01:00"/>
<ad:detail-page url="http://suchen.mobile.de/auto-inserat/mercedes-benz-200-hamburg/3.html"/>
<!-- [...] -->
</ad:ad>
<!-- [...] -->
My composer.json:
"require": {
"php": "~7.0",
"symfony/options-resolver": "~2.3|~3.0",
"goetas-webservices/xsd2php-runtime":"^0.2.2",
"jms/serializer": "1.5.0-RC1",
"php-http/guzzle6-adapter": "^1.1",
"php-http/mock-client": "^0.3"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"goetas-webservices/xsd2php":"^0.2"
},
latests versions are installed.
The property "ads" of "SearchResult" seems to be empty. Do you have any ideas to solve my problem ?
you can clone my repository from here https://github.com/robinlehrmann/mobile-de-api to debug it
Thank you very much!
I have developed a bundle (non public) for the same purpose (mobile.de API) and encountered the same problem. You just need to correct the ad namespace:
xml_root_name: search-result
xml_root_namespace: 'http://services.mobile.de/schema/search'
properties:
[...]
ads:
expose: true
access_type: public_method
serialized_name: ads
xml_element:
namespace: 'http://services.mobile.de/schema/search'
accessor:
getter: getAds
setter: setAds
type: array<Mobile\Ad\Ad>
xml_list:
inline: false
entry_name: ad
namespace: 'http://services.mobile.de/schema/ad' <---- here
@ama-gi you save my day! It's working now. Thank you very much. Do you think there is a bug in this library or do you think it came from mobile.de ?
The xsd files from mobile.de look fine to me, I think its a bug. The errors xml list probably has the same problem, i think it should be:
errors:
[...]
xml_list:
inline: false
entry_name: error
namespace: 'http://services.mobile.de/schema/common/error-1.0'
instead of
errors:
[...]
xml_list:
inline: false
entry_name: error
namespace: 'http://services.mobile.de/schema/search'
I guess maybe this library ignores the ref attribute for the child elements (ref="ad:ad")?
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://services.mobile.de/schema/search" xmlns:search="http://services.mobile.de/schema/search" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ad="http://services.mobile.de/schema/ad" xmlns:error="http://services.mobile.de/schema/common/error-1.0" elementFormDefault="qualified">
<xs:import namespace="http://services.mobile.de/schema/ad" schemaLocation="ad-1.0.xsd"/>
<xs:import namespace="http://services.mobile.de/schema/common/error-1.0" schemaLocation="common/error-1.0.xsd"/>
<xs:element name="result">
<xs:complexType>
<xs:sequence>
<xs:element ref="ad:ad" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="total" use="required" type="xs:int"/>
<xs:attribute name="page-size" use="required" type="xs:int"/>
<xs:attribute name="current-page" use="required" type="xs:int"/>
<xs:attribute name="max-pages" use="required" type="xs:int"/>
</xs:complexType>
</xs:element>
<xs:element name="search-result">
<xs:annotation>
<xs:documentation>The ad-search-result including some metadata, probably warnings and the ads (for this
page).
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="total" type="xs:int">
<xs:annotation>
<xs:documentation>The total number of results.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="page-size" type="xs:int">
<xs:annotation>
<xs:documentation>The number of results per page.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="current-page" type="xs:int">
<xs:annotation>
<xs:documentation>The current page number.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="max-pages" type="xs:int">
<xs:annotation>
<xs:documentation>The total number of results-pages.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element ref="error:errors" minOccurs="0"> <------ HERE
<xs:annotation>
<xs:documentation>A list of non fatal errors related to this search request e.g. invalid or
deprecated search parameters. If this list is present then the search result might not be as
intended by the client, so always check that this not present.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="ads">
<xs:annotation>
<xs:documentation>The ad results (of this page).</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element ref="ad:ad" minOccurs="0" maxOccurs="unbounded"/> <------ HERE
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="event-type">
<xs:restriction base="xs:string">
<xs:enumeration value="AD_CREATE_OR_UPDATE">
<xs:annotation>
<xs:documentation/>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="AD_DELETE">
<xs:annotation>
<xs:documentation/>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="ERROR">
<xs:annotation>
<xs:documentation/>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:element name="event">
<xs:complexType>
<xs:sequence>
<xs:element name="event-type" type="search:event-type" minOccurs="0"/>
<xs:element name="ad-key" type="xs:token" minOccurs="0"/>
<xs:element ref="ad:ad" minOccurs="0"/>
<xs:element ref="error:errors" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>`
Okay, we should try to fix that via a pull-request. I will look for it as soon as posible.
@robinlehrmann any news?
@goetas No, I'm sorry, currently I haven't enough time to resolve it.
Anyone had a work around or any solid solution for this?