kingson-de/marshal-xml-serializer

Marshal XML 可以将数据结构序列化为 XML。它还可以将 XML 反序列化为数据结构。

v1.2.1 2018-11-05 23:07 UTC

This package is auto-updated.

Last update: 2024-09-15 11:42:59 UTC


README

Marshal Serializer logo

License Build Status Code Coverage Scrutinizer Code Quality

介绍

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::serializeCollectionMarshalXml::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 许可协议 发布。