Skip to content

DOMDXMLParser is a class that can handle multiple CRUD tasks with XML files using The DOMDocument class

License

Notifications You must be signed in to change notification settings

tcja/DOMDXMLParser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Menu

DOMDXMLParser

DOMDXMLParser is a class that can handle multiple CRUD tasks with XML files

This class currently only supports the following XML layout examples

Simple layout with one level node along with attributes (default layout) :

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

or a layout with 2 levels nodes comprising each data in a single node without any attributes :

<?xml version="1.0" encoding="UTF-8"?>
<accounts>
  <account>
    <id>1</id>
    <type>supreme admin</type>
    <email>[email protected]</email>
    <name>Supreme Admin</name>
    <password>$2y$12$BsNUcdEIoN2GeFLucqmfbuiGOWzHyCfxpOczswgMZXqrsmYZx363O</password>
    <description>Supreme admin account</description>
  </account>
  <account>
    <id>2</id>
    <type>admin</type>
    <email>[email protected]</email>
    <name>First Admin</name>
    <password>$2y$12$jZGZuXODSvBXTQXtvguHTOnXxdFgamQvWumSBYQ11bkCWR/tG5ZIu</password>
    <description>Admin account</description>
  </account>
  <account>
    <id>3</id>
    <type>admin</type>
    <email>[email protected]</email>
    <name>Second Admin</name>
    <password>$2y$12$pCPyVWZWAtXNLYBoCKTlY.pxZhEJEq6Rf8JV0eDsjo6sArkzTYyqi</password>
    <description>Admin account</description>
  </account>
  <account>
    <id>4</id>
    <type>user</type>
    <email>[email protected]</email>
    <name>First User</name>
    <password>$2y$12$ZoNNlEc9LjXjBynueyqljO5pai.ZVz4RjLZxMdLxBijwwRd5H70OS</password>
    <description>User account</description>
  </account>
  <account>
    <id>5</id>
    <type>user</type>
    <email>[email protected]</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>[email protected]</email>
    <name>Third User</name>
    <password>$2y$12$pGQw1CMCryJu5j0FcPVqiORo3/g.Fkv78TaDAcy5m68UO//L8XQYS</password>
    <description>User account</description>
  </account>
</accounts>

How to install

Using composer : composer require tcja/domdxmlparser

or just download the class itself and install it manually

Read, check and compare data methods

Check a node existance by its value or by its attribute/value pair : suppose we want to check a user's e-mail existence from an email attribute :

// 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', '[email protected]');
var_dump($check); // Output : true if email was found, false if not

to check that same e-mail using the non-attribute layout style :

$check = $xml->checkNode('[email protected]');

Collect data from a specific node and have them stored in an array : suppose we want to get all data from the user with the e-mail [email protected] :

$data = $xml->pickNode('email', '[email protected]')->fetchData()->toArray();
var_dump($data);

Output :

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

To do that according to the non-attribute layout style, just select the node by its value :

$data = $xml->pickNode('[email protected]')->fetchData()->toArray();

Get an attribute value from a specific node :

$value = $xml->pickNode('email', '[email protected]')->getAttr('name');
var_dump($value); // Output : "Second User";

To do that according to the non-attribute layout style, pass the tag name as an argument to getValue() method :

$value = $xml->pickNode('[email protected]')->getValue('name');

Get a node value :

$value = $xml->pickNode('email', '[email protected]')->getValue();
var_dump($value); // Output : "User account";

To do that according to the non-attribute layout style, pass the tag name as an argument to getValue() method :

$value = $xml->pickNode('[email protected]')->getValue('description');

Get all nodes data :

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

Output :

array(6) {
  [0]=>
  array(6) {
    ["id"]=>
    string(1) "1"
    ["type"]=>
    string(13) "supreme admin"
    ["email"]=>
    string(22) "[email protected]"
    ["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) "[email protected]"
    ["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) "[email protected]"
    ["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) "[email protected]"
    ["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) "[email protected]"
    ["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) "[email protected]"
    ["name"]=>
    string(10) "Third User"
    ["password"]=>
    string(60) "$2y$12$pGQw1CMCryJu5j0FcPVqiORo3/g.Fkv78TaDAcy5m68UO//L8XQYS"
    ["nodeValue"]=>
    string(12) "User account"
  }
}

Sort the results by a specific attribute : suppose we want to sort the previous data by email in ascending order :

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

Output :

array(6) {
  [0]=>
  array(6) {
    ["id"]=>
    string(1) "2"
    ["type"]=>
    string(5) "admin"
    ["email"]=>
    string(20) "[email protected]"
    ["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) "[email protected]"
    ["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) "[email protected]"
    ["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) "[email protected]"
    ["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) "[email protected]"
    ["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) "[email protected]"
    ["name"]=>
    string(10) "Third User"
    ["password"]=>
    string(60) "$2y$12$pGQw1CMCryJu5j0FcPVqiORo3/g.Fkv78TaDAcy5m68UO//L8XQYS"
    ["nodeValue"]=>
    string(12) "User account"
  }
}

To sort in descending order, pass DESC value to sortBy() second attribute like so :

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

Please note that sortBy() method also sorts numerical values.

Get a specific attribute value from all nodes : suppose we want to get all users e-mail :

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

Output :

array(6) {
  [0]=>
  string(22) "[email protected]"
  [1]=>
  string(20) "[email protected]"
  [2]=>
  string(21) "[email protected]"
  [3]=>
  string(19) "[email protected]"
  [4]=>
  string(20) "[email protected]"
  [5]=>
  string(19) "[email protected]"
}

Get data from all nodes which match a specific attribute value : suppose we want to get data from the users that have an admin type account :

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

Output :

array(2) {
  [0]=>
  array(6) {
    ["id"]=>
    string(1) "2"
    ["type"]=>
    string(5) "admin"
    ["email"]=>
    string(20) "[email protected]"
    ["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) "[email protected]"
    ["name"]=>
    string(12) "Second Admin"
    ["password"]=>
    string(60) "$2y$12$pCPyVWZWAtXNLYBoCKTlY.pxZhEJEq6Rf8JV0eDsjo6sArkzTYyqi"
    ["nodeValue"]=>
    string(13) "Admin account"
  }
}

Compare an attribute value with the previous one in the same node : suppose we want to check if the password input from a login form corresponds to the password stored in the XML file :

$checkPassword = $xml->pickNode('email', '[email protected]')->compareTo('password', '$2y$12$zXk23k.usjDgjbG6yJAKtO9EohFFAwnMOzsY3CZsKrgonz3/kh97a');
vard_dump($checkPassword); // Output : true

Get the highest value amongst all nodes : suppose we want to get the user with the highest ID :

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

Get the total amount of items from the DOM :

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

Edit, add and remove data methods

Add a new node in the XML file : suppose we want to add a new user, first we pass the name of the node and then we can pass an array of attributes and values :

$xml->addNode('account', [
    'id' => 7, 
    'type' => 'user', 
    'email' => '[email protected]', 
    '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
]);

If using the non-attribute layout style, by default the nodes values will be written in pure text, if we want to use CDATA instead, we just have to set true to addNode()'s third argument like so :

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

If there is no data in the XML file yet and you want to add a node using the non-attribute layout style, please use the setLayoutStyleNoAttributes() method and pass true to its attribute before using addNode() method like so :

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

If there is already data in the XML file, we don't need to specify the layout style as the class will guess it for us and add the data accordingly.

Change node values : suppose we want to change some data for user with ID "3" (change its email and its user type to "user") :

$xml->pickNode('id', 3)->changeData([
    'type' => 'user', 
    'email' => '[email protected]'
]);

To change only one attribute value, we can just pass the attribute as a the first argument and its value to the second one :

$xml->pickNode('id', 3)->changeData('email', '[email protected]');

Add a new attribute : suppose we want to add a new attribute/value to that user, just pass the new attribute and value as you would do to change one like shown above :

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

Remove an attribute : suppose we want to remove the newly created attribute above, we would just pass false as the second argument to changeData() method from the targeted attribute like so :

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

Change specific attributes to all nodes : suppose we want to reset all users name to "NAME RESET", we pick account node and then pass an array with the new value to changeData() method :

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

Set new node value : suppose we want to set a new node value using CDATA to the user with the name "Third User", use setValue() method :

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

to do it using pure text, use setTextValue() method instead :

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

Remove a node from the XML file : suppose the user with the e-mail "[email protected]" wants to remove his account :

$xml->pickNode('email', '[email protected]')->remove();

Requirements

PHP 7.1 or above

PSR-4 autoload if using composer

Dependencies

PHP-Unit for unit testing

License

Released under the MIT License

Changelog

v1.2 :

Added a new way to remove an attribute, renamed a method and added unit testing :

  • Renamed DOMDXMLParser::setLayoutStyle($style) to DOMDXMLParser::setLayoutStyleNoAttributes($style) for better readability
  • Remove an attribute by passing false to the second argument of DOMDXMLParser::changData() method like so : $xml->pickNode('id', 3)->changeData('newAttribute', false);
  • Added unit testing for the default layout style, requires PHP Unit to perform them

v1.1.1 :

Fixed minor bugs (DOMDXMLParser::getTotalItems() method wasn't calculating items correctly), improved code, added a new method :

  • DOMDXMLParser::checkLayoutStyle() : Checks the current DOM layout style

v1.1 :

Fixed some bugs, improved some code, also added three new methods :

  • DOMDXMLParser::setLayoutStyle($style) : changes layout style node to single node -> value pair if set to true

  • DOMDXMLParser::getHighestValue($selector) : shows the highest value of $selector amongst all the nodes

  • DOMDXMLParser::getTotalItems() : shows the total number of items in the DOM

About

DOMDXMLParser is a class that can handle multiple CRUD tasks with XML files using The DOMDocument class

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages