fillup / array2xml
将数组转换为XML的库
Requires (Dev)
- phpunit/phpunit: ^4.8.24
This package is auto-updated.
Last update: 2024-09-06 08:48:57 UTC
README
array2xml 是一个简单的将数组转换为XML的库
为什么?
虽然有几个库可以将数组转换为XML,但它们都需要特殊的语法来注释模式细节,比如指定数组项发送方式、属性和命名空间。
我正在寻找一种解决方案,允许其他库的消费者提供数组,而无需了解这些XML模式细节。
如何工作
此库将数组数据与模式数据分开,因此非常适合在需要模式细节但不想将其强加给库用户的情况下使用。在实例化 fillup\A2X
类时,您将数据数组作为第一个参数传递,并提供一个带有模式细节的第二个数组参数(可选)。
此库支持序列化关联数组、常规数组、添加属性和命名空间。
模式数组是一个简单的关联数组格式,其中键是数组的路径/位置,值是一个包含模式细节的数组。
关联数组
关联数组是最容易序列化为XML的,因为格式 ['key' => 'value']
很自然地映射到 <key>value</key>
。
非关联数组
在PHP中,我们表示常规数组的方式类似于 ['item1', 'item2', 'item3']
,但将它们序列化为XML时会有挑战,因为每个元素都必须被标签包装。这可以通过使用特定位置的方案中的 sendItemsAs
元素来完成。下面是一个例子,其中数组中的 contacts 元素是一个关联数组数组。方案定义了将每个元素发送为 contact
。
A2X 还识别简单的复数形式,因此如果数组数据元素的名称为 contacts
,并且您没有指定其项的发送方式,它将删除尾随的 s
并将每个项发送为 contact
。
属性
如果您需要在XML中使用属性,例如 <contact type="email"><value>name@domain.com</value></contact>
,您可以通过在XML中需要属性的方案位置定义属性数组来完成此操作。方案中 attributes
数组的值与应序列化为属性的子元素相关。这使得在原始数组中非常自然地说
[ 'contact' => [ 'type' => 'email', 'value' => 'name@domain.com', ] ]
并在方案中提供
[ '/path/to/contact' => [ 'attributes' => [ 'type' ] ] ]
下面是一个例子,说明如何为 /person
和 /person/contacts/contact
提供属性。
命名空间
如果您需要在XML中使用命名空间,有两个地方可以定义它们。首先,您必须提供实际的命名空间定义,即从命名空间前缀到URI的映射。这些在方案数组的特殊 @namespaces
元素中提供。其次,对于方案数组中的任何给定位置,您都可以指定一个具有单个字符串值的 namespace
属性,该值应映射到 @attributes
中定义的前缀之一。下面是一个例子,说明如何将 ns1
和 ns2
定义在 @attributes
中,然后用于 /person/contacts
和 /person/contacts/contact
的位置。
如果您希望特定位置及其下的所有元素都具有相同的命名空间,您可以在方案中使用 childNamespace
属性。这将将给定的命名空间应用于给定位置以下的所有元素。
不包含父包装标签的列表元素
如果您需要生成一个没有包裹父标签的元素列表,可以将 includeWrappingTag
的模式设置设置为 false
。默认情况下,如果未设置,则视为 true
。这在以下示例中很有用,其中您有一个 children
列表,但希望每个元素都作为 child
元素列出,而不是作为 <children><child></child><child></child><children>
。
<?php use fillup\A2X; $data = [ 'person' => [ 'name' => 'Daddio', 'children' => [ [ 'name' => 'Older Brother', ], [ 'name' => 'Little Sister', [ ] ] ]; $schema = [ '/person/children' => [ 'sendItemsAs' => 'child', 'includeWrappingTag' => false, ], ]; $a2x = new A2X($data, $schema); $xml = $a2x->asXml();
在这个例子中,$xml
(如果格式化)将是
<?xml version="1.0" encoding="UTF-8"?> <person> <name>Daddio</name> <child> <name>Older Brother</name> </child> <child> <name>Little Sister</name> </child> </person>
用法
<?php use fillup\A2X; $data = [ 'person' => [ 'attributeName' => 'attribute value', 'name' => [ 'given' => 'first', 'surname' => 'last', ], 'address' => [ 'street1' => '123 Somewhere', 'street2' => '', 'city' => 'Anytown', 'state' => 'AA', 'country' => 'USA', ], 'age' => 40, 'contacts' => [ [ 'type' => 'email', 'value' => 'user@domain.com', ], [ 'type' => 'mobile', 'value' => '11235551234', ], ], ], ]; $schema = [ '/person' => [ 'attributes' => [ 'attributeName', ], ], '/person/contacts' => [ 'sendItemsAs' => 'contact', 'namespace' => 'ns1', 'childNamespace' => 'ns2', ], '/person/contacts/contact' => [ 'attributes' => [ 'type', ], ], '@namespaces' => [ 'ns1' => 'http://namespaceone.com', 'ns2' => 'http://namespacetwo.com', ], ]; $a2x = new A2X($data, $schema); $xml = $a2x->asXml();
在上面的例子中,$xml
将包含以下字符串
<?xml version="1.0" encoding="UTF-8"?> <person xmlns:ns1="http://namespaceone.com" xmlns:ns2="http://namespacetwo.com" attributeName="attribute value"> <name> <given>first</given> <surname>last</surname> </name> <address> <street1>123 Somewhere</street1> <street2></street2> <city>Anytown</city> <state>AA</state> <country>USA</country> </address> <age>40</age> <ns1:contacts> <ns2:contact type="email"> <ns2:value>user@domain.com</ns2:value> </ns2:contact> <ns2:contact type="mobile"> <ns2:value>11235551234</ns2:value> </ns2:contact> </ns1:contacts> </person>
A2X 目前不支持将 xml 格式化成这里显示的样式,但我将其格式化以便于阅读。
贡献
欢迎以问题或更好的方式提交 pull request。如果您喜欢这个库并使用它,请告诉我,我很乐意知道其他人是否也从中受益。phillip dot shipley at gmail。
许可证
MIT 许可证 (MIT)
版权所有 (c) 2016 Phillip Shipley
特此授予,免费,任何获得此软件及其相关文档副本(“软件”)的人,在不受限制的情况下处理软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,以及允许向提供软件的人这样做,前提是符合以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“原样”提供,不提供任何形式的保证,无论是明示的还是暗示的,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论是在合同、侵权或其他法律行为中产生的,无论该索赔、损害或其他责任是否与软件或其使用或其他方式有关。