xsd2php

repository·master·Indexed 42 days ago

https://github.com/goetas-webservices/xsd2php

A tool for converting XSD (XML Schema Definition) or WSDL definitions into PHP classes. It generates JMS Serializer compatible metadata for serialization and deserialization, and can transform XSD schema restrictions into Symfony Validation Constraints.

Tokens
4.3K
Snippets
16
Records
20
Agent score
54%

What's inside xsd2php

  1. Handle xsd:anyType and xsd:anySimpleType with custom handlers

    master

    If your XSD contains xsd:anyType or xsd:anySimpleType, you must map these to custom handlers in your config.yml using the aliases key. You then implement a class that implements SubscribingHandlerInterface to define how serialization and deserialization should behave for these types.

    # config.yml
    xsd2php:
      aliases: 
        'http://www.w3.org/2001/XMLSchema':
          anyType: 'MyCustomAnyTypeHandler'
          anySimpleType: 'MyCustomAnySimpleTypeHandler'
    use JMS\\Serializer\\Handler\\SubscribingHandlerInterface;
    use JMS\\Serializer\\GraphNavigator;
    
    class MyHandler implements SubscribingHandlerInterface
    {
        public static function getSubscribingMethods()
        {
            return [
                [
                    'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
                    'format' => 'xml',
                    'type' => 'MyCustomAnyTypeHandler',
                    'method' => 'deserializeAnyType'
                ],
                [
                    'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                    'format' => 'xml',
                    'type' => 'MyCustomAnyTypeHandler',
                    'method' => 'serializeAnyType'
                ]
            ];
        }
    
        public function serializeAnyType($visitor, $data, array $type, $context)
        {
            // implementation
        }
    
        public function deserializeAnyType($visitor, $data, array $type)
        {
            // implementation
        }
    }
  2. Choose the correct Naming Strategy

    master

    When converting XML names to PHP classes, you can choose between two strategies:

    1. short (Default): Generates concise class names. Use this if you do not have naming conflicts between elements and types.
    2. long: Suffixes elements with Element and types with Type (e.g., User becomes UserElement or UserType). Use this if your XSD has overlapping names for elements and types (e.g., a type named User and an element named User).
  3. How to use generated classes with JMS Serializer

    master

    The generated JMS metadata allows you to serialize and deserialize PHP objects using the JMS Serializer. You must register default handlers (like BaseTypesHandler and XmlSchemaDateHandler) and point the builder to your generated metadata directory.

    <?php
    
    use JMS\
    Serializer\\SerializerBuilder;
    use JMS\\Serializer\\Handler\\HandlerRegistryInterface;
    use GoetasWebservices\\Xsd\\XsdToPhpRuntime\\Jms\\Handler\\BaseTypesHandler;
    use GoetasWebservices\\Xsd\\XsdToPhpRuntime\\Jms\\Handler\\XmlSchemaDateHandler;
    
    $serializerBuilder = SerializerBuilder::create();
    $serializerBuilder->addMetadataDir('metadata dir', 'TestNs');
    $serializerBuilder->configureHandlers(function (HandlerRegistryInterface $handler) use ($serializerBuilder) {
        $serializerBuilder->addDefaultHandlers();
        $handler->registerSubscribingHandler(new BaseTypesHandler());
        $handler->registerSubscribingHandler(new XmlSchemaDateHandler());
    });
    
    $serializer = $serializerBuilder->build();
    
    // Deserialize XML into an object
    $object = $serializer->deserialize('<some xml/>', 'TestNs\\MyObject', 'xml');
    
    // Serialize object back to XML
    $newXml = $serializer->serialize($object, 'xml');
  4. Install xsd2php via Composer

    master

    To use xsd2php, add the runtime as a production dependency and the converter as a development dependency in your composer.json file.

    "require": {
        "goetas-webservices/xsd2php-runtime":"^0.2.2"
    },
    "require-dev": {
        "goetas-webservices/xsd2php":"^0.3"
    }
  5. How YamlValidatorConverter maps XSD restrictions to Symfony Validation Constraints

    master

    The YamlValidatorConverter is a specialized converter that extends YamlConverter to transform XSD schema restrictions into Symfony Validation Constraints for use in JMS YAML files.

    When generating validation metadata, it maps specific XSD facets to the following Symfony constraints:

    • enumeration $\rightarrow$ Choice (with type-casting for int and float)
    • length $\rightarrow$ Length (sets both min and max to the same value)
    • maxLength $\rightarrow$ Length (sets max)
    • minLength $\rightarrow$ Length (sets min)
    • pattern $\rightarrow$ Regex (includes automatic translation of Unicode blocks like \p{IsBasicLatin} to PHP-compatible hex ranges)
    • maxExclusive $\rightarrow$ LessThan
    • maxInclusive $\rightarrow$ LessThanOrEqual
    • minExclusive $\rightarrow$ GreaterThan
    • minInclusive $\rightarrow$ GreaterThanOrEqual

    Additionally, it handles structural constraints:

    • Required Elements/Attributes: Maps to NotNull.
    • Arrays: Uses Count for min/max occurrences and wraps element constraints in an All constraint to ensure every item in the array satisfies the rules.
  6. Configure xsd2php via config.yml

    master

    The conversion process requires a YAML configuration file to map XML namespaces to PHP namespaces and define output directories.

    Important for Linux Users: Use backslashes (\) for PHP namespaces in the configuration (e.g., TestNs\MyApp). On Windows, you may use forward slashes (/) if preferred, but backslashes are the standard for PHP namespaces.

    Key configuration sections:

    • xsd2php.namespaces (Required): Maps XML namespaces to PHP namespaces.
    • xsd2php.destinations_php (Required): Directory for generated PHP classes.
    • xsd2php.destinations_jms (Required): Directory for JMS Serializer metadata.
    • xsd2php.aliases (Optional): Maps specific XML types to custom PHP classes to bypass metadata generation.
    • xsd2php.naming_strategy (Optional): Use short (default) or long to avoid naming conflicts.
    • xsd2php.path_generator (Optional): Strategy for file saving (default is psr4).
    xsd2php:
      namespaces:
        'http://www.example.org/test/': 'TestNs\MyApp'
      destinations_php: 
        'TestNs\MyApp': soap/src
      destinations_jms:
        'TestNs\MyApp': soap/metadata
      aliases: 
        'http://www.example.org/test/':
          MyCustomXSDType: 'MyCustomMappedPHPType'
      naming_strategy: short
      path_generator: psr4
  7. Configure validation groups for generated Symfony constraints

    master

    When using YamlValidatorConverter, the generated Symfony validation rules (except for the Valid constraint) are automatically assigned to a specific validation group: xsd_rules.

    This allows you to trigger the XSD-derived validations separately from other application validation logic by specifying the group in your validation call.

  8. Instantiate PHPClass using createFromFQCN()

    master

    The PHPClass class can be instantiated from a Fully Qualified Class Name (FQCN). The createFromFQCN() static method automatically parses the string to separate the class name from its namespace.

    use GoetasWebservices\Xsd\XsdToPhp\Php\Structure\PHPClass;
    
    // If the FQCN is 'TestNs\MyApp\MyClass'
    // It will create a PHPClass with name 'MyClass' and namespace 'TestNs\MyApp'
    $phpClass = PHPClass::createFromFQCN('TestNs\MyApp\MyClass');
  9. Use PhpConverter to generate PHP classes from XSD schemas

    master

    The PhpConverter class is the primary engine for converting XSD (XML Schema Definition) schemas into PHP class structures. It uses a NamingStrategy to determine how XSD elements and types are named in PHP and requires a mapping of XSD namespaces to PHP namespaces.

    To use it, instantiate the converter with a naming strategy and a logger, then call convert() passing an array of Schema objects. The method returns an associative array where keys are the fully qualified class names and values are the corresponding PHPClass objects.

    use GoetasWebservices\Xsd\XsdToPhp\Php\PhpConverter;
    use GoetasWebservices\Xsd\XsdToPhp\Naming\YourNamingStrategy;
    
    $converter = new PhpConverter(new YourNamingStrategy(), $logger);
    $phpClasses = $converter->convert($schemas);
    
    foreach ($phpClasses as $fqcn => $phpClass) {
        // $phpClass is an instance of PHPClass representing the generated structure
    }
  10. Check if a PHP class should be skipped using isSkip()

    master

    The isSkip(PHPClass $class): bool method allows you to determine if a generated PHPClass is marked to be skipped. This typically happens for types that are considered 'base' schemas or types that are handled via aliases rather than direct class generation.

    if ($converter->isSkip($somePhpClass)) {
        // This class is marked to be skipped during generation
    }