aydin-hassan/xml-fuse

一个用于使用XPath合并数据的小型库

0.4.0 2015-07-31 12:10 UTC

This package is auto-updated.

Last update: 2024-09-12 20:36:28 UTC


README

Build Status Coverage Status Scrutinizer Code Quality Latest Stable Version Latest Untable Version

一个用于合并来自多个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',
]

然后对每个节点重复此过程。

注意

  1. 可以给出任意数量的XPath,如果它们没有返回结果,则不会进行合并,而是返回父节点。
  2. 您可以使用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