i-complex / xsd2php
将 XSD (XML Schema) 定义转换为 PHP 类和 JMS 元数据
Requires
- php: >=7.2|^8.0
- doctrine/inflector: ^2.0
- i-complex/xsd-reader: ^0.1
- laminas/laminas-code: ^3.3.2|^4.0
- psr/log: ^1.0 | ^2.0 | ^3.0
- symfony/config: ^2.2|^3.0|^4.0|^5.0|^6.0
- symfony/console: ^2.7|^3.0|^4.0|^5.0|^6.0
- symfony/dependency-injection: ^2.2|^3.0|^4.0|^5.0|^6.0
- symfony/yaml: ^2.2|^3.0|^4.0|^5.0|^6.0
Requires (Dev)
- dms/phpunit-arraysubset-asserts: ^0.3.1
- goetas-webservices/xsd2php-runtime: ^0.2.13@dev
- jms/serializer: ^1.9|^2.0|^3.0
- phpunit/phpunit: ^6.0|^7.0|^8.0|^9.0
- symfony/validator: ^2.3.24|^3.0|^4.0|^5.0|^6.0
This package is not auto-updated.
Last update: 2024-09-27 04:43:37 UTC
README
将 XSD 转换为 PHP 类。
使用 goetas-webservices/xsd2php
,您可以将任何 XSD/WSDL 定义转换为 PHP 类。
XSD2PHP 还可以生成与 JMS Serializer 兼容的元数据,可用于序列化/反序列化对象实例。
安装
通过 Composer 安装 xsd2php 是一种推荐的方式
- 将依赖项添加到您的
composer.json
文件中
"require": { .. "goetas-webservices/xsd2php-runtime":"^0.2.2", .. }, "require-dev": { .. "goetas-webservices/xsd2php":"^0.3", .. },
用法
在这个例子中,我们将把 OTA XSD 定义 转换为 PHP 类。
假设您所有的 XSD 文件都在 /home/my/ota
中,首先我们需要一个配置文件(例如 config.yml
),它将保存所有命名空间和目录映射信息。
# config.yml # Linux Users: PHP Namespaces use back slash \ rather than a forward slash / # So for destinations_php, the namespace would be TestNs\MyApp xsd2php: namespaces: 'http://www.example.org/test/': 'TestNs\MyApp' destinations_php: 'TestNs\MyApp': soap/src # 'TestNs\MyApp': soap\src # on Windows destinations_jms: 'TestNs\MyApp': soap/metadata # 'TestNs\MyApp': soap\metadata # on Windows # Uncomment this section if you want to have also symfony/validator metadata to be generated from XSD # destinations_validation: # 'TestNs\MyApp': soap/validation # 'TestNs\MyApp': soap\validation # on Windows aliases: # optional 'http://www.example.org/test/': MyCustomXSDType: 'MyCustomMappedPHPType' naming_strategy: short # optional and default path_generator: psr4 # optional and default # known_locations: # optional # "http://www.example.org/test/somefile.xsd": somefile.xsd # known_namespace_locations: # optional # "urn:veloconnect:catalog-1.1": xsd/catalog-1.1.xsd # configs_jms: #optional # xml_cdata: false # Disables CDATA
以下是每个参数意义的说明
-
xsd2php.namespaces
(必需)定义了 XML 命名空间和 PHP 命名空间之间的映射。 (在示例中,http://www.example.org/test/
XML 命名空间映射到TestNs\MyApp
) -
xsd2php.destinations_php
(必需)指定保存属于TestNs\MyApp
PHP 命名空间 PHP 类的目录。 (在这个示例中,TestNs\MyApp
类将被保存到soap/src
目录中。) -
xsd2php.destinations_jms
(必需)指定保存属于TestNs\MyApp
PHP 命名空间 JMS Serializer 元数据文件的目录。 (在这个示例中,TestNs\MyApp
元数据将被保存到soap/metadata
目录中。) -
xsd2php.aliases
(可选)指定了一些由自定义 JMS serializer 处理器处理的映射。 允许指定不要为某些 XML 类型生成元数据,并直接分配一个 PHP 类。为此,需要为该 PHP 类创建一个自定义 JMS 序列化/反序列化处理器。 -
xsd2php.naming_strategy
(可选)指定在将 XML 名称转换为 PHP 类时使用的命名策略。 -
xsd2php.path_generator
(可选)指定用于路径生成和文件保存的策略 -
xsd2php.known_locations
(可选)用本地文件覆盖远程位置。 -
xsd2php.known_namespace_locations
(可选)通过命名空间指定模式位置。 这可以用于读取导入命名空间但未指定 schemaLocation 属性的模式。 -
xsd2php.configs_jms.xml_cdata
(可选)指定在序列化时是否应使用 CDATA。
生成 PHP 类和 JMS 元数据信息
vendor/bin/xsd2php convert config.yml /home/my/ota/OTA_Air*.xsd
此命令将为匹配 /home/my/ota/OTA_Air*.xsd
的所有 XSD 文件生成 PHP 类和 JMS 元数据文件,并使用 config.yml
中的配置。
序列化/反序列化
XSD2PHP 还可以为您生成 JMS Serializer 元数据,您可以使用这些元数据来序列化/反序列化生成的 PHP 类实例。
配置文件中的 aliases
参数将指示 XSD2PHP 不要为 {http://www.example.org/test/}MyCustomXSDType
类型生成任何元数据信息或 PHP 类。所有对此类型的引用都将替换为 MyCustomMappedPHPType
名称。
您必须为此类型/别名提供一个 自定义序列化器。
以下是一个配置JMS序列化器以处理自定义类型的示例
<?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()); // 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/>', 'TestNs\MyObject', 'xml'); // some code .... // serialize the Demo\MyObject back into XML $newXml = $serializer->serialize($object, 'xml');
要禁用CDATA,请按如下配置JMS
xsd2php: configs_jms: xml_cdata: false
验证
<?php use Symfony\Component\Validator\Validation; // get the validator $builder = Validation::createValidatorBuilder(); foreach (glob('soap/validation/*.yml') as $file) { $builder->addYamlMapping($file); } $validator = $builder->getValidator(); // validate $object $violations = $validator->validate($object, null, ['xsd_rules']);
处理xsd:anyType
或xsd:anySimpleType
如果您的XSD包含xsd:anyType
或xsd:anySimpleType
类型,您必须指定一个处理程序。
当您生成JMS元数据时,必须指定一个自定义处理程序
# config.yml xsd2php: ... aliases: 'http://www.w3.org/2001/XMLSchema': anyType: 'MyCustomAnyTypeHandler' anySimpleType: 'MyCustomAnySimpleTypeHandler'
现在您必须创建一个自定义序列化处理程序
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 } }
命名策略
有两种类型的命名策略:short
和long
。默认是short
,但这种命名策略可能会生成命名冲突。
long
命名策略将在元素后缀Element
,在类型后缀Type
。
MyNamespace\User
将变为MyNamespace\UserElement
MyNamespace\UserType
将变为MyNamespace\UserTypeType
例如,一个XSD,其中有一个名为User
的类型,一个名为UserType
的类型,一个根元素名为User
和UserElement
,只有在使用long
命名策略时才能正常工作。
- 如果您没有命名冲突并且希望有简短且描述性的类名,请使用
short
选项。 - 如果您有命名冲突,请使用
long
选项。 - 如果您想确保安全,请使用
long
选项。
注意
本项目的代码在MIT许可证下提供。如需专业支持,请联系goetas@gmail.com或访问https://www.goetas.com