kingson-de / marshal-xml-serializer
Marshal XML 可以将数据结构序列化为 XML。它还可以将 XML 反序列化为数据结构。
Requires
- php: ^7.0
- ext-dom: *
- kingson-de/marshal-serializer: ^1.3
Requires (Dev)
- phpunit/phpunit: ^6.5
README
介绍
Marshal XML 可以 序列化 / 打包 数据结构为 XML。它还可以反序列化 / 解包 XML 为数据结构。
安装
通过 composer 安装库是最简单的方式
composer require kingson-de/marshal-xml-serializer
以下 PHP 版本得到支持
- PHP 7.0
- PHP 7.1
- PHP 7.2
- PHP 7.3
执行测试
只需运行
composer test
或者不使用代码覆盖率
composer quicktest
用法
如何创建可序列化的数据结构?
请查看 Marshal Serializer README 以获取更多信息。
如何使用 Marshal XML 序列化器库?
一旦定义了数据结构,库提供了一些静态方法来创建 XML 数据。
<?php use KingsonDe\Marshal\Data\Item; use KingsonDe\Marshal\MarshalXml; $xml = MarshalXml::serialize(new Item($mapper, $model)); // or $xml = MarshalXml::serializeItem($mapper, $model); // or $xml = MarshalXml::serializeItemCallable(function (User $user) { return [ 'root' => [ 'username' => $user->getUsername(), 'email' => $user->getEmail(), 'birthday' => $user->getBirthday()->format('Y-m-d'), 'followers' => count($user->getFollowers()), ], ]; }, $user);
请注意,MarshalXml::serializeCollection
和 MarshalXml::serializeCollectionCallable
方法不可用。XML 中的集合不能在根级别生成。但是,在定义根节点后,您可以在任何地方使用集合。
如何定义 XML 属性?
如果您使用的是扩展 AbstractXmlMapper 的具体实现,可以使用 attributes
方法。
<?php use KingsonDe\Marshal\AbstractXmlMapper; class RootMapper extends AbstractXmlMapper { public function map(){ return [ 'root' => [ $this->attributes() => [ 'xmlns' => 'http://example.org/xml', ], ], ]; } }
如果您使用的是可调用对象,则需要使用 MarshalXml::ATTRIBUTES_KEY
常量。
<?php use KingsonDe\Marshal\MarshalXml; $xml = MarshalXml::serializeItemCallable(function () { return [ 'root' => [ MarshalXml::ATTRIBUTES_KEY => [ 'xmlns' => 'http://example.org/xml', ], ], ]; });
这将生成
<?xml version="1.0" encoding="UTF-8"?> <root xmlns="http://example.org/xml"/>
如何定义 XML 节点值?
这很简单
<?php use KingsonDe\Marshal\MarshalXml; $xml = MarshalXml::serializeItemCallable(function (User $user) { return [ 'root' => [ 'user' => $user->getUsername(), ], ]; }, $user);
这将生成
<?xml version="1.0" encoding="UTF-8"?> <root> <user>Kingson</user> </root>
如何定义 XML 节点值为 CDATA?
然后您必须使用具体 Mapper 实现的 cdata
方法或可调用的 MarshalXml::CDATA_KEY
。
<?php use KingsonDe\Marshal\AbstractXmlMapper; class UserMapper extends AbstractXmlMapper { public function map(User $user){ return [ 'root' => [ 'user' => $this->cdata($user->getUsername()), ], ]; } }
<?php use KingsonDe\Marshal\MarshalXml; $xml = MarshalXml::serializeItemCallable(function (User $user) { return [ 'root' => [ 'user' => [ MarshalXml::CDATA_KEY => $user->getUsername(), ], ], ]; }, $user);
这将生成
<?xml version="1.0" encoding="UTF-8"?> <root> <user><![CDATA[Kingson]]></user> </root>
但如果节点还有属性怎么办?
那么您必须使用具体 Mapper 实现的 data
/ cdata
方法或可调用的 MarshalXml::DATA_KEY
/ MarshalXml::CDATA_KEY
。
<?php use KingsonDe\Marshal\AbstractXmlMapper; class UserMapper extends AbstractXmlMapper { public function map(User $user){ return [ 'root' => [ 'user' => [ $this->attributes() => [ 'xmlns' => 'http://example.org/xml', ], $this->data() => $user->getUsername(), ], 'userCDATA' => [ $this->attributes() => [ 'xmlns' => 'http://example.org/xml', ], $this->cdata() => $user->getUsername(), ], ], ]; } }
<?php use KingsonDe\Marshal\MarshalXml; $xml = MarshalXml::serializeItemCallable(function (User $user) { return [ 'root' => [ 'user' => [ MarshalXml::ATTRIBUTES_KEY => [ 'xmlns' => 'http://example.org/xml', ], MarshalXml::DATA_KEY => $user->getUsername(), ], 'userCDATA' => [ MarshalXml::ATTRIBUTES_KEY => [ 'xmlns' => 'http://example.org/xml', ], MarshalXml::CDATA_KEY => $user->getUsername(), ], ], ]; }, $user);
这将生成
<?xml version="1.0" encoding="UTF-8"?> <root> <user xmlns="http://example.org/xml">Kingson</user> <userCDATA xmlns="http://example.org/xml"><![CDATA[Kingson]]></userCDATA> </root>
反序列化 / 解包
要将 XML 转换回您的结构,请使用 Marshal 的反序列化函数。您需要一个扩展 AbstractObjectMapper 的类,该类将传递给 deserializeXml 函数。
<?php use KingsonDe\Marshal\AbstractObjectMapper; use KingsonDe\Marshal\Data\FlexibleData; use KingsonDe\Marshal\MarshalXml; class AcmeExampleIdMapper extends AbstractObjectMapper { public function map(FlexibleData $flexibleData, ...$additionalData) { return $flexibleData ->get('container') ->get('acme-example:config') ->get('acme-example:id') ->get(MarshalXml::CDATA_KEY); } }
<?php use KingsonDe\Marshal\MarshalXml; $id = MarshalXml::deserializeXml($xml, new AcmeExampleIdMapper());
另一种选择是使用 deserializeCallable 函数。
<?php use KingsonDe\Marshal\MarshalXml; $id = MarshalXml::deserializeXmlCallable($xml, function (FlexibleData $flexibleData) { return $flexibleData['container']['acme-example:config']['acme-example:id'][MarshalXml::CDATA_KEY]; });
修改现有的 XML
使用 FlexibleData 是修改现有 XML 的简单方法。以下是一个示例
<?php use KingsonDe\Marshal\Data\FlexibleData; use KingsonDe\Marshal\MarshalXml; $xml = '<?xml version="1.0" encoding="UTF-8"?><root><tag>Hello World!</tag></root>'; $flexibleData = new FlexibleData(MarshalXml::deserializeXmlToData($xml)); $flexibleData['root']['tag'] = 'some other text'; $modifiedXml = MarshalXml::serialize($flexibleData);
许可证
本项目按照 Apache 2.0 许可协议 发布。