Generate PHP classes: vendor/goetas/xsd2php/bin/xsd2php.php convert:php UBL-Invoice-2.0.xsd --ns-map='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2;UBL\Invoice' --ns-map='urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2;UBL\Common ExtensionComponents' --ns-map='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2;UBL\CommonBasicComponents' --ns-map='urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2;UBL\UnqualifiedDataTypesSchema Module' --ns-map='urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2;UBL\QualifiedDatatypes' --ns-map='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2;UBL\CommonAggregateComponents' --ns-map='urn:un:unec e:uncefact:codelist:specification:66411:2001;UBL\CodeList\Specification\IANAMIMEMediaType' --ns-map='urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003;UBL\Codelist\Specification\IANAMIMEMediaType' --ns-map='urn:un:unece:uncef act:codelist:specification:54217:2001;UBL\CodeList\Specification\54217' --ns-map='urn:un:unece:uncefact:codelist:specification:5639:1988;UBL\CodeList\Specification\5639' --ns-dest='UBL;src/UBL' --ns-dest=';src/UBL'
Generate YML files: vendor/goetas/xsd2php/bin/xsd2php.php convert:jms-yaml UBL-Invoice-2.0.xsd --ns-map='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2;UBL\Invoice' --ns-map='urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2;UBL\C ommonExtensionComponents' --ns-map='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2;UBL\CommonBasicComponents' --ns-map='urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2;UBL\UnqualifiedDataTypesS chemaModule' --ns-map='urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2;UBL\QualifiedDatatypes' --ns-map='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2;UBL\CommonAggregateComponents' --ns-map='urn:un :unece:uncefact:codelist:specification:66411:2001;UBL\CodeList\Specification\IANAMIMEMediaType' --ns-map='urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003;UBL\Codelist\Specification\IANAMIMEMediaType' --ns-map='urn:un:unece: uncefact:codelist:specification:54217:2001;UBL\CodeList\Specification\54217' --ns-map='urn:un:unece:uncefact:codelist:specification:5639:1988;UBL\CodeList\Specification\5639' --ns-dest='UBL;src/UBL' --ns-dest=';src/UBL'
Convert XSD into PHP classes.
With goetas/xsd2php you can convert any XSD/WSDL definition into PHP classes.
XSD2PHP can also generate JMS Serializer compatible metadata that can be used to serialize/unserialize the object instances.
There is one recommended way to install xsd2php via Composer:
- adding the dependency to your
composer.jsonfile:
"require": {
..
"goetas/xsd2php":"2.*@dev",
"goetas/xsd-reader":"2.*@dev",
"jms/serializer": "xsd2php-dev as 0.18.0",
..
}
"repositories": [{
"type": "vcs",
"url": "https://github.com/goetas/serializer.git"
}],This package requires a patched version of JMS Serializer. In the last year the activity of JMS serializer was very low and some features required by this project was rejected or not yet reviewed ( #301, #222 )
With this example we will convert OTA XSD definitions into PHP classes.
Suppose that you have allo XSD files in /home/my/ota.
vendor/bin/xsd2php convert:php \
`/home/my/ota/OTA_HotelAvail*.xsd \
--ns-map='http://www.opentravel.org/OTA/2003/05;Mercurio/OTA/2007B/' \
--ns-dest='Mercurio/OTA/2007B/;src/Mercurio/OTA/V2007B' \
--alias-map='http://www.opentravel.org/OTA/2003/05;CustomOTADateTimeFormat;Vendor/Project/CustomDateClass'
What about namespaces?
http://www.opentravel.org/OTA/2003/05will be converted intoMercurio/OTA/2007BPHP namespace
Where place the files?
Mercurio/OTA/2007Bclasses will be placed intosrc/Mercurio/OTA/V2007Bdirectory
What about custom types?
--alias-map='http://www.opentravel.org/OTA/2003/05;CustomOTADateTimeFormat;Vendor/Project/CustomDateClass'will instruct XSD2PHP to not generate any class forCustomOTADateTimeFormattype inside thehttp://www.opentravel.org/OTA/2003/05namespace. All reference to this type are replaced with theVendor/Project/CustomDateClassclass.
"scripts": {
"build": "xsd2php convert:php '/home/my/ota/OTA_HotelAvail*.xsd' --ns-map='http://www.opentravel.org/OTA/2003/05;Mercurio/OTA/2007B/' --ns-dest='Mercurio/OTA/2007B/;src/Mercurio/OTA/V2007B'"
}Now you can build your classes with composer build.
XSD2PHP can also generate for you JMS Serializer metadata that you can use to serialize/unserialize the generated PHP class instances.
vendor/bin/xsd2php convert:jms-yaml \
`/home/my/ota/OTA_HotelAvail*.xsd \
--ns-map='http://www.opentravel.org/OTA/2003/05;Mercurio/OTA/2007B/' \
--ns-dest='Mercurio/OTA/2007B/;src/Metadata/JMS;' \
--alias-map='http://www.opentravel.org/OTA/2003/05;CustomOTADateTimeFormat;Vendor/Project/CustomDateClass'
What about namespaces?
http://www.opentravel.org/OTA/2003/05will be converted intoMercurio/OTA/2007BPHP namespace
Where place the files?
http://www.opentravel.org/OTA/2003/05will be placed intosrc/Metadata/JMSdirectory
What about custom types?
--alias-map='http://www.opentravel.org/OTA/2003/05;CustomOTADateTimeFormat;Vendor/Project/CustomDateClass'will instruct XSD2PHP to not generate any metadata information forCustomOTADateTimeFormattype inside thehttp://www.opentravel.org/OTA/2003/05namespace. All reference to this type are replaced with theVendor/Project/CustomDateClassclass. You have to provide a custom serializer for this type
use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\Handler\HandlerRegistryInterface;
use Goetas\Xsd\XsdToPhp\Jms\Handler\BaseTypesHandler;
use Goetas\Xsd\XsdToPhp\Jms\Handler\XmlSchemaDateHandler;
$serializerBuilder = SerializerBuilder::create();
$serializerBuilder->addMetadataDir('metadata dir', 'DemoNs');
$serializerBuilder->configureHandlers(function (HandlerRegistryInterface $handler) use ($serializerBuilder) {
$serializerBuilder->addDefaultHandlers();
$handler->registerSubscribingHandler(new BaseTypesHandler()); // XMLSchema List handling
$handler->registerSubscribingHandler(new XmlSchemaDateHandler()); // XMLSchema date handling
// $handler->registerSubscribingHandler(new YourhandlerHere());
});
$serializer = $serializerBuilder->build();
// deserialize the XML into Demo\MyObject object
$object = $serializer->deserialize('<some xml/>', 'DemoNs\MyObject', 'xml');
// some code ....
// serialize the Demo\MyObject back into XML
$newXml = $serializer->serialize($object, 'xml');If your XSD contains xsd:anyType or xsd:anySimpleType types you have to specify a handler for this.
When you generate the JMS metadata you have to specify a custom handler:
bin/xsd2php.php convert:jms-yaml \
... various params ... \
--alias-map='http://www.w3.org/2001/XMLSchema;anyType;MyCustomAnyTypeHandler' \
--alias-map='http://www.w3.org/2001/XMLSchema;anyType;MyCustomAnySimpleTypeHandler' \
Now you have to create a custom serialization handler:
use JMS\Serializer\XmlSerializationVisitor;
use JMS\Serializer\XmlDeserializationVisitor;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\VisitorInterface;
use JMS\Serializer\Context;
class MyHandler implements SubscribingHandlerInterface
{
public static function getSubscribingMethods()
{
return array(
array(
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'xml',
'type' => 'MyCustomAnyTypeHandler',
'method' => 'deserializeAnyType'
),
array(
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'xml',
'type' => 'MyCustomAnyTypeHandler',
'method' => 'serializeAnyType'
)
);
}
public function serializeAnyType(XmlSerializationVisitor $visitor, $data, array $type, Context $context)
{
// serialize your object here
}
public function deserializeAnyType(XmlDeserializationVisitor $visitor, $data, array $type)
{
// deserialize your object here
}
}There are two types of naming strategies: short and long. The default is short, this naming strategy can however generate naming conflicts.
The long naming strategy will suffix elements with Element and types with Type.
MyNamesapce\Userwill becomeMyNamesapce\UserElementMyNamesapce\UserTypewill becomeMyNamesapce\UserTypeType
An XSD for instance with a type named User, a type named UserType, a root element named User and UserElement, will only work when using the long naming strategy.
- If you don't have naming conflicts and you want to have short and descriptive class names, use the
--naming-strategy=shortoption. - If you have naming conflicts use the
--naming-strategy=longoption. - If you want to be safe, use the
--naming-strategy=longoption.
I'm sorry for the terrible written english within the documentation, I'm trying to improve it. Pull Requests are welcome.

