Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,50 @@ on:
jobs:
Build:
runs-on: 'ubuntu-latest'
container: 'byjg/php:${{ matrix.php-version }}-cli'
container:
image: 'byjg/php:${{ matrix.php-version }}-cli'
options: --user root --privileged
strategy:
matrix:
php-version:
- "8.5"
- "8.4"
- "8.3"
- "8.2"
- "8.1"

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- run: composer install
- run: ./vendor/bin/phpunit
- run: composer test

Psalm:
name: Psalm Static Analyzer
runs-on: ubuntu-latest
permissions:
# for github/codeql-action/upload-sarif to upload SARIF results
security-events: write
container:
image: byjg/php:8.4-cli
options: --user root --privileged

steps:
- name: Git checkout
uses: actions/checkout@v4

- name: Composer
run: composer install

- name: Psalm
# Note: Ignoring error code 2, which just signals that some
# flaws were found, not that Psalm itself failed to run.
run: ./vendor/bin/psalm
--show-info=true
--report=psalm-results.sarif || [ $? = 2 ]

- name: Upload Analysis results to GitHub
uses: github/codeql-action/upload-sarif@v4
if: github.ref == 'refs/heads/master'
with:
sarif_file: psalm-results.sarif

Documentation:
if: github.ref == 'refs/heads/master'
Expand All @@ -32,5 +64,6 @@ jobs:
with:
folder: php
project: ${{ github.event.repository.name }}
secrets: inherit
secrets:
DOC_TOKEN: ${{ secrets.DOC_TOKEN }}

6 changes: 6 additions & 0 deletions .run/PHPUnit.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="PHPUnit" type="PHPUnitRunConfigurationType" factoryName="PHPUnit">
<TestRunner configuration_file="$PROJECT_DIR$/phpunit.xml.dist" scope="XML" use_alternative_configuration_file="true" />
<method v="2" />
</configuration>
</component>
8 changes: 8 additions & 0 deletions .run/psalm.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="psalm" type="ComposerRunConfigurationType" factoryName="Composer Script">
<option name="commandLineParameters" value="" />
<option name="pathToComposerJson" value="$PROJECT_DIR$/composer.json" />
<option name="script" value="psalm" />
<method v="2" />
</configuration>
</component>
35 changes: 35 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug current Script in Console",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9003,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
"env": {
"XDEBUG_MODE": "debug,develop",
"XDEBUG_CONFIG": "client_port=${port}"
}
},
{
"name": "PHPUnit Debug",
"type": "php",
"request": "launch",
"program": "${workspaceFolder}/vendor/bin/phpunit",
"cwd": "${workspaceFolder}",
"port": 9003,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
"env": {
"XDEBUG_MODE": "debug,develop",
"XDEBUG_CONFIG": "client_port=${port}"
}
}
]
}
158 changes: 38 additions & 120 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,44 @@
# AnyDataset-Xml

[![Build Status](https://github.com/byjg/php-anydataset-xml/actions/workflows/phpunit.yml/badge.svg?branch=master)](https://github.com/byjg/php-anydataset-xml/actions/workflows/phpunit.yml)
[![Opensource ByJG](https://img.shields.io/badge/opensource-byjg-success.svg)](http://opensource.byjg.com)
[![GitHub source](https://img.shields.io/badge/Github-source-informational?logo=github)](https://github.com/byjg/php-anydataset-xml/)
[![GitHub license](https://img.shields.io/github/license/byjg/php-anydataset-xml.svg)](https://opensource.byjg.com/opensource/licensing.html)
[![Sponsor](https://img.shields.io/badge/Sponsor-%23ea4aaa?logo=githubsponsors&logoColor=white&labelColor=0d1117)](https://github.com/sponsors/byjg)
[![Build Status](https://github.com/byjg/php-anydataset-xml/actions/workflows/phpunit.yml/badge.svg?branch=master)](https://github.com/byjg/php-anydataset-xml/actions/workflows/phpunit.yml)
[![Opensource ByJG](https://img.shields.io/badge/opensource-byjg-success.svg)](http://opensource.byjg.com)
[![GitHub source](https://img.shields.io/badge/Github-source-informational?logo=github)](https://github.com/byjg/php-anydataset-xml/)
[![GitHub license](https://img.shields.io/github/license/byjg/php-anydataset-xml.svg)](https://opensource.byjg.com/opensource/licensing.html)
[![GitHub release](https://img.shields.io/github/release/byjg/php-anydataset-xml.svg)](https://github.com/byjg/php-anydataset-xml/releases/)

XML abstraction dataset. Anydataset is an agnostic data source abstraction layer in PHP.

See more about Anydataset [here](https://opensource.byjg.com/php/anydataset).

## Examples

### Simple Manipulation

example1.xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="COOKING">
<title lang="en-US">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="de-DE">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="pt-BR">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
XML abstraction dataset for the AnyDataset library. AnyDataset is an agnostic data source abstraction layer in PHP.

## Features

- **Simple XML Processing**: Process XML data with a clean, consistent API
- **XPath Support**: Use XPath expressions to select nodes and attributes
- **Namespace Support**: Full support for XML namespaces
- **Repeated Node Handling**: Automatically handles repeated nodes by returning arrays
- **Custom Field Processing**: Define custom field mappings with closures/callbacks
- **Flexible Input**: Accept XML as string, DOMDocument, XmlNode, or File object
- **AnyDataset Integration**: Compatible with the AnyDataset abstraction layer

## Documentation

- [XmlDataset](docs/XmlDataset.md) - Main class for working with XML data
- [XPath Expressions](docs/XPath-Expressions.md) - Guide to using XPath in the library

## Installation

```bash
composer require "byjg/anydataset-xml"
```

example1.php
## Quick Example

```php
<?php
$xml = file_get_contents('example1.xml');
$xml = file_get_contents('example.xml');

$dataset = new \ByJG\AnyDataset\Xml\XmlDataset(
$xml, // The Xml
"book", // The node that represents a row
$xml, // The XML string, can also be an XmlNode, DOMDocument, or File object
"book", // The node that represents a row
[
"category" => "@category",
"title" => "title",
Expand All @@ -60,99 +52,25 @@ $dataset = new \ByJG\AnyDataset\Xml\XmlDataset(
$iterator = $dataset->getIterator();
foreach ($iterator as $row) {
echo $row->get('category'); // Print COOKING, CHILDREN, WEB
echo $row->get('title'); // Print Everyday Italian, Harry Potter, Learning Xml
echo $row->get('title'); // Print Everyday Italian, Harry Potter, Learning XML
echo $row->get('lang'); // Print en-US, de-DE, pt-BR
echo $row->get('lang2'); // Print en, de, pt
}
```

### Xml with namespaces

example2.xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gContact="http://schemas.google.com/contact/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
<id>myId</id>
<updated>2014-09-15T19:35:55.795Z</updated>
<category scheme="http://schemas.google.com/g/2005#kind" term="gContact#contact"/>
<title type="text">Title</title>
<link rel="alternate" type="text/html" href="https://www.google.com/"/>
<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/my%40gmail.com/full"/>
<link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/my%40gmail.com/full"/>
<link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/my%40gmail.com/full/batch"/>
<link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/my%40gmail.com/full?max-results=20"/>
<link rel="next" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/my%40gmail.com/full?max-results=20&amp;start-index=21"/>
<author>
<name>My Name</name>
<email>My Email</email>
</author>
<generator version="1.0" uri="http://www.google.com/m8/feeds">Contacts</generator>
<openSearch:totalResults>2107</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>20</openSearch:itemsPerPage>
<entry>
<id>http://www.google.com/m8/feeds/contacts/my%40gmail.com/base/0</id>
<updated>2013-10-05T22:16:03.564Z</updated>
<category scheme="http://schemas.google.com/g/2005#kind" term="gContact#contact"/>
<title type="text">Person 1</title>
<link rel="http://schemas.google.com/contacts/2008/rel#edit-photo" type="image/*" href="https://www.google.com/m8/feeds/photos/media/my%40gmail.com/1/ABCDE"/>
<link rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*" href="https://www.google.com/m8/feeds/photos/media/my%40gmail.com/1"/>
<link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/my%40gmail.com/full/0"/>
<link rel="edit" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/my%40gmail.com/full/0/1234"/>
<gd:email rel="http://schemas.google.com/g/2005#other" address="p1@gmail.com" primary="true"/>
</entry>
<entry>
<id>http://www.google.com/m8/feeds/contacts/my%40gmail.com/base/1</id>
<updated>2012-07-12T17:19:17.546Z</updated>
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
<title type="text">Person 2</title>
<link rel="http://schemas.google.com/contacts/2008/rel#edit-photo" type="image/*" href="https://www.google.com/m8/feeds/photos/media/my%40gmail.com/1/EDFGH"/>
<link rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*" href="https://www.google.com/m8/feeds/photos/media/my%40gmail.com/1"/>
<link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/my%40gmail.com/full/1"/>
<link rel="edit" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/my%40gmail.com/full/1/5678"/>
<gd:email rel="http://schemas.google.com/g/2005#other" address="p2@gmail.com" primary="true"/>
</entry></feed>
```

example2.php
```php
<?php
$xml = file_get_contents('example2.xml')

$namespace = array(
"fake" => "http://www.w3.org/2005/Atom",
"gd" => "http://schemas.google.com/g/2005"
);

$rootNode = 'fake:entry';
$colNode = array("id" => "fake:id", "updated" => "fake:updated", "name" => "fake:title", "email" => "gd:email/@address");
$xmlDataset = new \ByJG\AnyDataset\Xml\XmlDataset(
$xml,
$rootNode,
$colNode,
$namespace
);
$xmlIterator = $xmlDataset->getIterator();
```

## Install
## Dependencies

```
composer require "byjg/anydataset-xml"
```mermaid
flowchart TD
byjg/anydataset-xml --> byjg/anydataset
byjg/anydataset-xml --> ext-dom
```

## Running the Unit tests
## Running the Unit Tests

```bash
vendor/bin/phpunit
```

## Dependencies

```mermaid
flowchart TD
byjg/anydataset-xml --> byjg/anydataset
byjg/anydataset-xml --> ext-dom
```
----
[Open source ByJG](http://opensource.byjg.com)
13 changes: 9 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "byjg/anydataset-xml",
"description": "Anydataset Xml abstraction. Anydataset is an agnostic data source abstraction layer in PHP.",
"description": "XML abstraction dataset for the AnyDataset library. AnyDataset is an agnostic data source abstraction layer in PHP.",
"autoload": {
"psr-4": {
"ByJG\\AnyDataset\\Xml\\": "src/"
Expand All @@ -14,15 +14,20 @@
"prefer-stable": true,
"minimum-stability": "dev",
"require": {
"php": ">=8.1 <8.4",
"php": ">=8.3 <8.6",
"ext-dom": "*",
"byjg/anydataset": "^5.0"
"byjg/anydataset": "^6.0"
},
"require-dev": {
"phpunit/phpunit": "^9.6"
"phpunit/phpunit": "^10.5|^11.5",
"vimeo/psalm": "^5.9|^6.13"
},
"provide": {
"byjg/anydataset-implementation": "1.0"
},
"scripts": {
"test": "vendor/bin/phpunit",
"psalm": "vendor/bin/psalm"
},
"license": "MIT"
}
Loading