aydin-hassan / xml-fuse
一个用于使用XPath合并数据的小型库
Requires
- php: >=5.4
Requires (Dev)
- phpunit/phpunit: ~4.1
- satooshi/php-coveralls: ~0.6
- squizlabs/php_codesniffer: 1.4.*
This package is auto-updated.
Last update: 2024-09-12 20:36:28 UTC
README
一个用于合并来自多个XPath的标量数据的小型库。类似于SQL Join,但使用XML。
如果您想将XML数据转换为平面格式,这个库很有用。这对于无源方法很有用。例如,您可能需要处理来自多个源的数据,但希望将它们都转换为类似的格式。
这个库旨在将三维数据转换为平面数组。以下是一个XML的示例
<?xml version="1.0" encoding="ISO-8859-1"?> <order> <orderId>01</orderId> <customerEmail>aydin@hotmail.co.uk</customerEmail> <lines> <line> <id>1</id> <qty>2</qty> <status>despatched</status> </line> <line> <id>5</id> <qty>1</qty> <status>despatched</status> </line> </lines> </order>
想象一个导入,它更新与订单关联的每个项目的状态。导入仅接受平面数组数据,并且一次只能处理一个项目。为了更新项目的状态,导入还必须知道订单ID,以便加载它并与其项目交互。
我们可以使用xpath循环每个订单项目,如下所示://order/lines/line
,这将给出所有项目信息,但我们仍然没有订单ID在数据中。如果我们能这样得到数据呢
array(2) { [0] => array(5) { 'orderId' => string(2) "01" 'customerEmail' => string(19) "aydin@hotmail.co.uk" 'id' => string(1) "1" 'qty' => string(1) "2" 'status' => string(10) "despatched" } [1] => array(5) { 'orderId' => string(2) "01" 'customerEmail' => string(19) "aydin@hotmail.co.uk" 'id' => string(1) "5" 'qty' => string(1) "1" 'status' => string(10) "despatched" } }
这种数据结构是每个<line>
节点中嵌入的父节点数据。我们可以将这些数据结构成功传递给我们的订单状态更新器类,它拥有完成其工作的所有数据。
安装
Composer
composer require aydin-hassan/xml-fuse
使用方法
要使用此工具,您应该实例化XmlFuser类,传入您的XML以及您想要组合的XPath。然后,您可以调用parse()
以获取返回的记录数组。
示例
$xml = '<?xml version="1.0" encoding="ISO-8859-1"?> <order> <orderId>01</orderId> <customerEmail>aydin@hotmail.co.uk</customerEmail> <lines> <line> <id>1</id> <qty>2</qty> <status>despatched</status> </line> <line> <id>5</id> <qty>1</qty> <status>despatched</status> </line> </lines> </order>'; $xPaths = [ '//order', 'lines/line' ]; $fuser = new \AydinHassan\XmlFuse\XmlFuse($xml, $xPaths); $res = $fuser->parse(); var_dump($res); //Output array(2) { [0] => array(5) { 'orderId' => string(2) "01" 'customerEmail' => string(19) "aydin@hotmail.co.uk" 'id' => string(1) "1" 'qty' => string(1) "2" 'status' => string(10) "despatched" } [1] => array(5) { 'orderId' => string(2) "01" 'customerEmail' => string(19) "aydin@hotmail.co.uk" 'id' => string(1) "5" 'qty' => string(1) "1" 'status' => string(10) "despatched" } }
发生了什么?
传递给解析器的每个XPath都将按提供的顺序进行处理。因此,将加载XML并执行第一个XPath搜索。这将生成一个节点数组(只有一个)。
节点中的每个数据项(不是嵌套结构)都将移动到数组中。因此,我们得到:orderId & customerEmail
[ 'orderId' => 1, 'customerEmail' => 'aydin@otmail.co.uk', ]
被跳过,因为它是一个嵌套结构。
现在从这个点开始,下一个XPath将被搜索,记住我们的当前位置? ()。我们的第二个XPath是:lines/line
,这将返回一个节点数组。
现在,每个节点的标量数据(非嵌套)被转换为数组。例如
[ 'id' => '1', 'qty' => '1', 'status' => 'despatched', ]
然后将其与父搜索的数据合并,即节点。这将留下我们
[ 'orderId' => 1, 'customerEmail' => 'aydin@otmail.co.uk', 'id' => '1', 'qty' => '1', 'status' => 'despatched', ]
然后对每个节点重复此过程。
注意
- 可以给出任意数量的XPath,如果它们没有返回结果,则不会进行合并,而是返回父节点。
- 您可以使用
setXPaths()
方法传入一组新的XPath,并调用parse()
方法重新解析XML。
贡献和运行测试
git clone git@github.com:AydinHassan/XmlFuse.git
cd XmlFuse
composer install
./vendor/bin/phpunit
//make sure you run the lint process aswell
./vendor/bin/phpcs --standard=PSR2 ./src
./vendor/bin/phpcs --standard=PSR2 ./test