tcja/domdxmlparser

DOMDXMLParser是一个类,可以借助DOMDocument类处理XML文件的多个CRUD(创建、读取、更新、删除)任务

1.2.1 2021-03-28 05:46 UTC

This package is auto-updated.

Last update: 2024-09-28 13:40:52 UTC


README

DOMDXMLParser

DOMDXMLParser是一个类,可以处理XML文件的多个CRUD任务

此类目前仅支持以下XML布局示例

单级节点及属性的简单布局(默认布局)

<?xml version="1.0" encoding="UTF-8"?>
<accounts>
  <account id="1" type="supreme admin" email="supreme-admin@mail.com" name="Supreme Admin" password="$2y$12$BsNUcdEIoN2GeFLucqmfbuiGOWzHyCfxpOczswgMZXqrsmYZx363O"><![CDATA[Supreme admin account]]></account>
  <account id="2" type="admin" email="first-admin@mail.com" name="First Admin" password="$2y$12$jZGZuXODSvBXTQXtvguHTOnXxdFgamQvWumSBYQ11bkCWR/tG5ZIu"><![CDATA[Admin account]]></account>
  <account id="3" type="admin" email="second-admin@mail.com" name="Second Admin" password="$2y$12$pCPyVWZWAtXNLYBoCKTlY.pxZhEJEq6Rf8JV0eDsjo6sArkzTYyqi"><![CDATA[Admin account]]></account>
  <account id="4" type="user" email="first-user@mail.com" name="First User" password="$2y$12$ZoNNlEc9LjXjBynueyqljO5pai.ZVz4RjLZxMdLxBijwwRd5H70OS"><![CDATA[User account]]></account>
  <account id="5" type="user" email="second-user@mail.com" name="Second User" password="$2y$12$zXk23k.usjDgjbG6yJAKtO9EohFFAwnMOzsY3CZsKrgonz3/kh97a"><![CDATA[User account]]></account>
  <account id="6" type="user" email="third-user@mail.com" name="Third User" password="$2y$12$pGQw1CMCryJu5j0FcPVqiORo3/g.Fkv78TaDAcy5m68UO//L8XQYS"><![CDATA[User account]]></account>
</accounts>

或包含单个节点内所有数据的2级节点布局,且没有属性

<?xml version="1.0" encoding="UTF-8"?>
<accounts>
  <account>
    <id>1</id>
    <type>supreme admin</type>
    <email>supreme-admin@mail.com</email>
    <name>Supreme Admin</name>
    <password>$2y$12$BsNUcdEIoN2GeFLucqmfbuiGOWzHyCfxpOczswgMZXqrsmYZx363O</password>
    <description>Supreme admin account</description>
  </account>
  <account>
    <id>2</id>
    <type>admin</type>
    <email>first-admin@mail.com</email>
    <name>First Admin</name>
    <password>$2y$12$jZGZuXODSvBXTQXtvguHTOnXxdFgamQvWumSBYQ11bkCWR/tG5ZIu</password>
    <description>Admin account</description>
  </account>
  <account>
    <id>3</id>
    <type>admin</type>
    <email>second-admin@mail.com</email>
    <name>Second Admin</name>
    <password>$2y$12$pCPyVWZWAtXNLYBoCKTlY.pxZhEJEq6Rf8JV0eDsjo6sArkzTYyqi</password>
    <description>Admin account</description>
  </account>
  <account>
    <id>4</id>
    <type>user</type>
    <email>first-user@mail.com</email>
    <name>First User</name>
    <password>$2y$12$ZoNNlEc9LjXjBynueyqljO5pai.ZVz4RjLZxMdLxBijwwRd5H70OS</password>
    <description>User account</description>
  </account>
  <account>
    <id>5</id>
    <type>user</type>
    <email>second-user@mail.com</email>
    <name>Second User</name>
    <password>$2y$12$zXk23k.usjDgjbG6yJAKtO9EohFFAwnMOzsY3CZsKrgonz3/kh97a</password>
    <description>User account</description>
  </account>
  <account>
    <id>6</id>
    <type>user</type>
    <email>third-user@mail.com</email>
    <name>Third User</name>
    <password>$2y$12$pGQw1CMCryJu5j0FcPVqiORo3/g.Fkv78TaDAcy5m68UO//L8XQYS</password>
    <description>User account</description>
  </account>
</accounts>

如何安装

使用composer: composer require tcja/domdxmlparser

或者直接下载类本身并手动安装

读取、检查和比较数据方法

通过值或属性/值对检查节点是否存在:假设我们想检查来自email属性的用户的电子邮件是否存在

// Since DOMDXMLParser uses method names such as sortBy() and toArray(),
// we use the class in its own namespace to avoid conflict with same methods
// names within famous frameworks like laravel or symfony
use Tcja\DOMDXMLParser;

$xml = new DOMDXMLParser('path/to/xml/file');
$check = $xml->checkNode('email', 'second-user@mail.com');
var_dump($check); // Output : true if email was found, false if not

使用非属性布局样式检查相同的电子邮件

$check = $xml->checkNode('second-user@mail.com');

从特定节点收集数据并将它们存储在数组中:假设我们想获取电子邮件为second-user@mail.com的用户的全部数据

$data = $xml->pickNode('email', 'second-user@mail.com')->fetchData()->toArray();
var_dump($data);

输出

array(6) {
  ["id"]=>
  string(1) "5"
  ["type"]=>
  string(4) "user"
  ["email"]=>
  string(20) "second-user@mail.com"
  ["name"]=>
  string(11) "Second User"
  ["password"]=>
  string(60) "$2y$12$zXk23k.usjDgjbG6yJAKtO9EohFFAwnMOzsY3CZsKrgonz3/kh97a"
  ["nodeValue"]=>
  string(12) "User account"
}

按照非属性布局样式,只需根据值选择节点

$data = $xml->pickNode('second-user@mail.com')->fetchData()->toArray();

从一个特定节点获取属性值

$value = $xml->pickNode('email', 'second-user@mail.com')->getAttr('name');
var_dump($value); // Output : "Second User";

按照非属性布局样式,将标签名称作为参数传递给getValue()方法

$value = $xml->pickNode('second-user@mail.com')->getValue('name');

获取节点值

$value = $xml->pickNode('email', 'second-user@mail.com')->getValue();
var_dump($value); // Output : "User account";

按照非属性布局样式,将标签名称作为参数传递给getValue()方法

$value = $xml->pickNode('second-user@mail.com')->getValue('description');

获取所有节点数据

$data = $xml->pickNode('account')->fetchData()->toArray();
var_dump($data);

输出

array(6) {
  [0]=>
  array(6) {
    ["id"]=>
    string(1) "1"
    ["type"]=>
    string(13) "supreme admin"
    ["email"]=>
    string(22) "supreme-admin@mail.com"
    ["name"]=>
    string(13) "Supreme Admin"
    ["password"]=>
    string(60) "$2y$12$BsNUcdEIoN2GeFLucqmfbuiGOWzHyCfxpOczswgMZXqrsmYZx363O"
    ["nodeValue"]=>
    string(21) "Supreme admin account"
  }
  [1]=>
  array(6) {
    ["id"]=>
    string(1) "2"
    ["type"]=>
    string(5) "admin"
    ["email"]=>
    string(20) "first-admin@mail.com"
    ["name"]=>
    string(11) "First Admin"
    ["password"]=>
    string(60) "$2y$12$jZGZuXODSvBXTQXtvguHTOnXxdFgamQvWumSBYQ11bkCWR/tG5ZIu"
    ["nodeValue"]=>
    string(13) "Admin account"
  }
  [2]=>
  array(6) {
    ["id"]=>
    string(1) "3"
    ["type"]=>
    string(5) "admin"
    ["email"]=>
    string(21) "second-admin@mail.com"
    ["name"]=>
    string(12) "Second Admin"
    ["password"]=>
    string(60) "$2y$12$pCPyVWZWAtXNLYBoCKTlY.pxZhEJEq6Rf8JV0eDsjo6sArkzTYyqi"
    ["nodeValue"]=>
    string(13) "Admin account"
  }
  [3]=>
  array(6) {
    ["id"]=>
    string(1) "4"
    ["type"]=>
    string(4) "user"
    ["email"]=>
    string(19) "first-user@mail.com"
    ["name"]=>
    string(10) "First User"
    ["password"]=>
    string(60) "$2y$12$ZoNNlEc9LjXjBynueyqljO5pai.ZVz4RjLZxMdLxBijwwRd5H70OS"
    ["nodeValue"]=>
    string(12) "User account"
  }
  [4]=>
  array(6) {
    ["id"]=>
    string(1) "5"
    ["type"]=>
    string(4) "user"
    ["email"]=>
    string(20) "second-user@mail.com"
    ["name"]=>
    string(11) "Second User"
    ["password"]=>
    string(60) "$2y$12$zXk23k.usjDgjbG6yJAKtO9EohFFAwnMOzsY3CZsKrgonz3/kh97a"
    ["nodeValue"]=>
    string(12) "User account"
  }
  [5]=>
  array(6) {
    ["id"]=>
    string(1) "6"
    ["type"]=>
    string(4) "user"
    ["email"]=>
    string(19) "third-user@mail.com"
    ["name"]=>
    string(10) "Third User"
    ["password"]=>
    string(60) "$2y$12$pGQw1CMCryJu5j0FcPVqiORo3/g.Fkv78TaDAcy5m68UO//L8XQYS"
    ["nodeValue"]=>
    string(12) "User account"
  }
}

按特定属性排序结果:假设我们想按电子邮件升序排序之前的数据

$data = $xml->pickNode('account')->fetchData()->sortBy('email')->toArray();
var_dump($data);

输出

array(6) {
  [0]=>
  array(6) {
    ["id"]=>
    string(1) "2"
    ["type"]=>
    string(5) "admin"
    ["email"]=>
    string(20) "first-admin@mail.com"
    ["name"]=>
    string(11) "First Admin"
    ["password"]=>
    string(60) "$2y$12$jZGZuXODSvBXTQXtvguHTOnXxdFgamQvWumSBYQ11bkCWR/tG5ZIu"
    ["nodeValue"]=>
    string(13) "Admin account"
  }
  [1]=>
  array(6) {
    ["id"]=>
    string(1) "4"
    ["type"]=>
    string(4) "user"
    ["email"]=>
    string(19) "first-user@mail.com"
    ["name"]=>
    string(10) "First User"
    ["password"]=>
    string(60) "$2y$12$ZoNNlEc9LjXjBynueyqljO5pai.ZVz4RjLZxMdLxBijwwRd5H70OS"
    ["nodeValue"]=>
    string(12) "User account"
  }
  [2]=>
  array(6) {
    ["id"]=>
    string(1) "3"
    ["type"]=>
    string(5) "admin"
    ["email"]=>
    string(21) "second-admin@mail.com"
    ["name"]=>
    string(12) "Second Admin"
    ["password"]=>
    string(60) "$2y$12$pCPyVWZWAtXNLYBoCKTlY.pxZhEJEq6Rf8JV0eDsjo6sArkzTYyqi"
    ["nodeValue"]=>
    string(13) "Admin account"
  }
  [3]=>
  array(6) {
    ["id"]=>
    string(1) "5"
    ["type"]=>
    string(4) "user"
    ["email"]=>
    string(20) "second-user@mail.com"
    ["name"]=>
    string(11) "Second User"
    ["password"]=>
    string(60) "$2y$12$zXk23k.usjDgjbG6yJAKtO9EohFFAwnMOzsY3CZsKrgonz3/kh97a"
    ["nodeValue"]=>
    string(12) "User account"
  }
  [4]=>
  array(6) {
    ["id"]=>
    string(1) "1"
    ["type"]=>
    string(13) "supreme admin"
    ["email"]=>
    string(22) "supreme-admin@mail.com"
    ["name"]=>
    string(13) "Supreme Admin"
    ["password"]=>
    string(60) "$2y$12$BsNUcdEIoN2GeFLucqmfbuiGOWzHyCfxpOczswgMZXqrsmYZx363O"
    ["nodeValue"]=>
    string(21) "Supreme admin account"
  }
  [5]=>
  array(6) {
    ["id"]=>
    string(1) "6"
    ["type"]=>
    string(4) "user"
    ["email"]=>
    string(19) "third-user@mail.com"
    ["name"]=>
    string(10) "Third User"
    ["password"]=>
    string(60) "$2y$12$pGQw1CMCryJu5j0FcPVqiORo3/g.Fkv78TaDAcy5m68UO//L8XQYS"
    ["nodeValue"]=>
    string(12) "User account"
  }
}

按降序排序,将DESC值传递给sortBy()第二个参数,如下所示

$data = $xml->pickNode('account')->fetchData()->sortBy('email', 'DESC')->toArray();

请注意,sortBy()方法也排序数值。

从所有节点获取特定属性值:假设我们想获取所有用户的电子邮件

$data = $xml->pickNode('account')->fetchData('email')->toArray();
var_dump($data);

输出

array(6) {
  [0]=>
  string(22) "supreme-admin@mail.com"
  [1]=>
  string(20) "first-admin@mail.com"
  [2]=>
  string(21) "second-admin@mail.com"
  [3]=>
  string(19) "first-user@mail.com"
  [4]=>
  string(20) "second-user@mail.com"
  [5]=>
  string(19) "third-user@mail.com"
}

从匹配特定属性值的节点获取数据:假设我们想获取拥有管理员type账户的用户的数据

$data = $xml->pickNode('type', 'admin')->fetchData()->toArray();
var_dump($data);

输出

array(2) {
  [0]=>
  array(6) {
    ["id"]=>
    string(1) "2"
    ["type"]=>
    string(5) "admin"
    ["email"]=>
    string(20) "first-admin@mail.com"
    ["name"]=>
    string(11) "First Admin"
    ["password"]=>
    string(60) "$2y$12$jZGZuXODSvBXTQXtvguHTOnXxdFgamQvWumSBYQ11bkCWR/tG5ZIu"
    ["nodeValue"]=>
    string(13) "Admin account"
  }
  [1]=>
  array(6) {
    ["id"]=>
    string(1) "3"
    ["type"]=>
    string(5) "admin"
    ["email"]=>
    string(21) "second-admin@mail.com"
    ["name"]=>
    string(12) "Second Admin"
    ["password"]=>
    string(60) "$2y$12$pCPyVWZWAtXNLYBoCKTlY.pxZhEJEq6Rf8JV0eDsjo6sArkzTYyqi"
    ["nodeValue"]=>
    string(13) "Admin account"
  }
}

比较同一节点中前一个属性值与当前值:假设我们想检查登录表单中输入的密码是否与XML文件中存储的密码匹配

$checkPassword = $xml->pickNode('email', 'second-user@mail.com')->compareTo('password', '$2y$12$zXk23k.usjDgjbG6yJAKtO9EohFFAwnMOzsY3CZsKrgonz3/kh97a');
vard_dump($checkPassword); // Output : true

获取所有节点中的最高值:假设我们想获取ID最高的用户

$highest_user_id = $xml->pickNode('account')->getHighestValue('id');
vard_dump($highest_user_id); // Output : 6

获取DOM中的项目总数

$total_items = $xml->getTotalItems();
vard_dump($total_items); // Output : 6

编辑、添加和删除数据方法

在XML文件中添加新节点:假设我们想添加新用户,首先我们传递节点名称,然后可以传递属性和值的数组

$xml->addNode('account', [
    'id' => 7, 
    'type' => 'user', 
    'email' => 'fourth-user@mail.com', 
    'name' => 'Fourth User', 
    'password' => '$2y$12$WOjspiqT7ZuuMMPGCeZJjuU4hguSpEV9TQSfnjZudGgF9PYj7OAEa', 
    'CDATA' => 'User account' // this will create a CDATA node value, if you just want pure text, use 'textNode' => 'value' instead
]);

如果使用非属性布局样式,默认情况下节点值将以纯文本形式写入,如果我们想使用CDATA,我们只需将true设置为addNode()的第三个参数,如下所示

$xml->addNode('account', [
    'id' => 7, 
    'type' => 'user', 
    'email' => 'fourth-user@mail.com', 
    'name' => 'Fourth User', 
    'password' => '$2y$12$WOjspiqT7ZuuMMPGCeZJjuU4hguSpEV9TQSfnjZudGgF9PYj7OAEa', 
    'description' => 'User account'
], true);

如果XML文件中还没有数据,并且您想使用非属性布局样式添加节点,请使用setLayoutStyleNoAttributes()方法,并在使用addNode()方法之前将true传递给其属性,如下所示

$xml->setLayoutStyleNoAttributes(true);
$xml->addNode('account', [
    'id' => 7, 
    'type' => 'user', 
    'email' => 'fourth-user@mail.com', 
    'name' => 'Fourth User', 
    'password' => '$2y$12$WOjspiqT7ZuuMMPGCeZJjuU4hguSpEV9TQSfnjZudGgF9PYj7OAEa', 
    'description' => 'User account'
]);

如果XML文件中已有数据,我们不需要指定布局样式,因为类会为我们猜测并相应地添加数据。

更改节点值:假设我们想更改ID为"3"的用户的一些数据(更改其电子邮件和用户类型为"user")

$xml->pickNode('id', 3)->changeData([
    'type' => 'user', 
    'email' => 'foo-bar@mail.com'
]);

要更改单个属性值,我们只需将属性作为第一个参数传递,将其值作为第二个参数传递即可

$xml->pickNode('id', 3)->changeData('email', 'foo-bar@mail.com');

添加新属性:假设我们想向该用户添加新的属性/值,就像上面更改一个那样,只需传递新的属性和值

$xml->pickNode('id', 3)->changeData('newAttribute', 'New value');

删除属性:假设我们想删除上面创建的新属性,我们只需将false作为changeData()方法的第二个参数传递给目标属性,如下所示

$xml->pickNode('id', 3)->changeData('newAttribute', false);

更改所有节点的特定属性:假设我们想将所有用户的名称重置为"NAME RESET",我们选择account节点,然后将包含新值的数组传递给changeData()方法

$xml->pickNode('account')->changeData(['name' => 'NAME RESET']);

设置新节点值:假设我们想使用CDATA设置名为"Third User"的用户的新节点值,使用setValue()方法

$xml->pickNode('name', 'Third User')->setValue('New node value');

如果使用纯文本,请使用setTextValue()方法代替

$xml->pickNode('name', 'Third User')->setTextValue('New node value');

从XML文件中删除节点:假设电子邮件为"second-user@mail.com"的用户想要删除其账户

$xml->pickNode('email', 'second-user@mail.com')->remove();

要求

PHP 7.1或更高版本

使用composer时,请启用PSR-4自动加载

依赖项

PHP-Unit用于单元测试

许可证

在MIT许可下发布

变更日志

v1.2 :

添加了删除属性的新方法,重命名了一个方法并添加了单元测试

  • DOMDXMLParser::setLayoutStyle($style)重命名为DOMDXMLParser::setLayoutStyleNoAttributes($style)以提高可读性
  • 通过将false传递给DOMDXMLParser::changeData()方法的第二个参数来删除属性:$xml->pickNode('id', 3)->changeData('newAttribute', false);
  • 添加了对默认布局样式的单元测试,需要PHP Unit来执行

v1.1.1 :

修复了小错误(DOMDXMLParser::getTotalItems()方法没有正确计算项目),改进了代码,添加了一个新方法

  • DOMDXMLParser::checkLayoutStyle():检查当前的DOM布局样式

v1.1 :

修复了一些错误,改进了一些代码,还添加了三个新方法

  • DOMDXMLParser::setLayoutStyle($style):如果设置为true,将布局样式节点更改为单节点 -> 值对

  • DOMDXMLParser::getHighestValue($selector):显示所有节点中$selector的最高值

  • DOMDXMLParser::getTotalItems():显示DOM中的项目总数