From 44557f6968f6f8877dd41d45b3e7cd1a1d7d0a5f Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Wed, 11 Dec 2024 10:48:57 -0600 Subject: [PATCH 1/6] Allow PHP 8.4 --- .github/workflows/phpunit.yml | 1 + composer.json | 8 ++++---- src/File.php | 4 ++-- src/XmlDocument.php | 13 ++++++++++--- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 402fee8..9aa23c6 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -16,6 +16,7 @@ jobs: strategy: matrix: php-version: + - "8.4" - "8.3" - "8.2" - "8.1" diff --git a/composer.json b/composer.json index 6fecd5b..c9de81e 100644 --- a/composer.json +++ b/composer.json @@ -14,15 +14,15 @@ "minimum-stability": "dev", "prefer-stable": true, "require": { - "php": ">=8.1 <8.4", + "php": ">=8.1 <8.5", "ext-dom": "*", "ext-libxml": "*", "ext-simplexml": "*", - "byjg/serializer": "^5.0" + "byjg/serializer": "^5.1" }, "require-dev": { - "phpunit/phpunit": "^9.6", - "vimeo/psalm": "^5.20" + "phpunit/phpunit": "^9.6|^10.5|^11.5", + "vimeo/psalm": "^6.0" }, "license": "MIT" } diff --git a/src/File.php b/src/File.php index db0c5fe..8c031b1 100644 --- a/src/File.php +++ b/src/File.php @@ -27,10 +27,10 @@ public function getFilename(): string } /** - * @return string + * @return string|bool * @throws FileException */ - public function getContents(): string + public function getContents(): string|bool { if (!file_exists($this->filename)) { throw new FileException('File not found'); diff --git a/src/XmlDocument.php b/src/XmlDocument.php index 8bee3c9..61c8163 100644 --- a/src/XmlDocument.php +++ b/src/XmlDocument.php @@ -88,12 +88,16 @@ public static function emptyDocument(string $name, ?string $namespace = null): X /** * Adjust xml string to the proper format * - * @param string $string - XML string document + * @param string|bool $string $string - XML string document * @return string - Return the string converted * @throws XmlUtilException */ - protected function fixXmlHeader(string $string): string + protected function fixXmlHeader(string|bool $string): string { + if ($string === false) { + throw new XmlUtilException("Error loading XML Document.", 250); + } + $string = $this->removeBom($string); if (str_contains($string, " Date: Wed, 11 Dec 2024 11:47:11 -0600 Subject: [PATCH 2/6] Allow PHP 8.4 --- composer.json | 2 +- phpunit.xml.dist | 16 ++++++++-------- src/Attributes/XmlEntity.php | 2 +- src/EntityParser.php | 2 +- src/XmlNode.php | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index c9de81e..68b7d51 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "byjg/serializer": "^5.1" }, "require-dev": { - "phpunit/phpunit": "^9.6|^10.5|^11.5", + "phpunit/phpunit": "^10.5|^11.5", "vimeo/psalm": "^6.0" }, "license": "MIT" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 13600e9..584610f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -9,24 +9,24 @@ and open the template in the editor. bootstrap="./vendor/autoload.php" colors="true" testdox="true" - convertErrorsToExceptions="true" - convertNoticesToExceptions="true" - convertWarningsToExceptions="true" - convertDeprecationsToExceptions="true" + displayDetailsOnTestsThatTriggerDeprecations="true" + displayDetailsOnTestsThatTriggerErrors="true" + displayDetailsOnTestsThatTriggerNotices="true" + displayDetailsOnTestsThatTriggerWarnings="true" + displayDetailsOnPhpunitDeprecations="true" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> - - + - ./src + ./src/ - + diff --git a/src/Attributes/XmlEntity.php b/src/Attributes/XmlEntity.php index eb44ee8..3e8e3dc 100644 --- a/src/Attributes/XmlEntity.php +++ b/src/Attributes/XmlEntity.php @@ -17,7 +17,7 @@ class XmlEntity private ?string $usePrefix; private bool $explicityMap = false; - public function __construct(?string $rootElementName = null, array $namespaces = [], bool $preserveCaseName = false, bool $addNamespaceRoot = true, string $usePrefix = null, bool $explicityMap = false) + public function __construct(?string $rootElementName = null, array $namespaces = [], bool $preserveCaseName = false, bool $addNamespaceRoot = true, ?string $usePrefix = null, bool $explicityMap = false) { $this->rootElementName = $rootElementName; $this->namespaces = $namespaces; diff --git a/src/EntityParser.php b/src/EntityParser.php index 669247b..6a822c4 100644 --- a/src/EntityParser.php +++ b/src/EntityParser.php @@ -105,7 +105,7 @@ protected function addNamespaces(XmlNode $xml, XmlEntity $metadata): void * @throws DOMException * @throws XmlUtilException */ - public function arrayToXml(object|array $array, XmlNode $xml, XmlEntity $rootMetadata = null): void + public function arrayToXml(object|array $array, XmlNode $xml, ?XmlEntity $rootMetadata = null): void { // The main Root document is not empty if (empty($rootMetadata)) { diff --git a/src/XmlNode.php b/src/XmlNode.php index e8554b0..e133251 100644 --- a/src/XmlNode.php +++ b/src/XmlNode.php @@ -261,7 +261,7 @@ public function removeTagName(string $tagName): bool } - public function toArray(Closure $func = null): array + public function toArray(?Closure $func = null): array { return $this->_toArray($this->DOMNode(), $func); } @@ -380,7 +380,7 @@ public function toString(bool $format = false, bool $noHeader = false): string return $this->_toString($this->DOMDocument(), $format, $this->node); } - protected function _toString(DOMDocument $domDocument, bool $format = false, DOMNode $node = null): string + protected function _toString(DOMDocument $domDocument, bool $format = false, ?DOMNode $node = null): string { if (!$format) { return $domDocument->saveXML($node); From 4f294ba6aab8fd6581957f5f93266f6879048207 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Thu, 13 Mar 2025 11:03:20 -0500 Subject: [PATCH 3/6] Adjusts on the Documentation --- README.md | 84 ++++++++++++++++++++---- docs/convert-model-xml-withattributes.md | 4 +- docs/file-handling.md | 62 +++++++++++++++++ docs/query-document.md | 2 +- docs/validate-document.md | 45 +++++++++++++ 5 files changed, 182 insertions(+), 15 deletions(-) create mode 100644 docs/file-handling.md create mode 100644 docs/validate-document.md diff --git a/README.md b/README.md index b1e2cd1..35327ae 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# XmlUtil +# PHP XML Util [![Build Status](https://github.com/byjg/php-xmlutil/actions/workflows/phpunit.yml/badge.svg?branch=master)](https://github.com/byjg/php-xmlutil/actions/workflows/phpunit.yml) [![Opensource ByJG](https://img.shields.io/badge/opensource-byjg-success.svg)](http://opensource.byjg.com) @@ -6,29 +6,90 @@ [![GitHub license](https://img.shields.io/github/license/byjg/php-xmlutil.svg)](https://opensource.byjg.com/opensource/licensing.html) [![GitHub release](https://img.shields.io/github/release/byjg/php-xmlutil.svg)](https://github.com/byjg/php-xmlutil/releases/) -A utility class to make it easy work with XML in PHP +A powerful and intuitive PHP library for working with XML documents. This utility makes XML manipulation, querying, +and conversion simple and straightforward in PHP. -## Examples +## Overview -- [Create a new XML Document using the API](docs/using-api.md) -- [Working with namespaces](docs/namespaces.md) -- [Query a XMLDocument](docs/query-document.md) -- [Convert any model to XML](docs/convert-model-xml.md) -- [Use Attributes to help in the conversion](docs/convert-model-xml-withattributes.md) -- [Clean an XML document removing specific tags](docs/clean-document.md) +PHP XML Util provides a comprehensive set of tools for XML manipulation in PHP applications. It simplifies common +XML operations with an intuitive API, allowing developers to create, modify, query, and validate XML documents +with minimal code. -## Install +The library is designed to be lightweight yet powerful, offering features that go beyond +PHP's built-in XML functionality while maintaining a clean and easy-to-use interface. + +## Key Features + +- **Simple XML Creation API** - Create and manipulate XML documents programmatically with an intuitive API +- **XPath Querying** - Easily query and navigate XML documents using XPath expressions +- **PHP Model ↔ XML Conversion** - Seamlessly convert between PHP objects and XML representations +- **Attribute-Based Mapping** - Use PHP attributes to control XML serialization behavior +- **Namespace Support** - Full support for XML namespaces in all operations +- **Document Cleaning** - Selectively remove specific tags from XML documents +- **XML Validation** - Validate XML documents against schemas +- **File Handling** - Convenient methods for loading and saving XML from/to files + +## Quick Example + +```php +'); + +// Build the document structure +$myNode = $xml->appendChild('mynode'); +$myNode->appendChild('subnode', 'text'); +$myNode->appendChild('subnode', 'more text'); +$otherNode = $myNode->appendChild('othersubnode', 'other text'); +$otherNode->addAttribute('attr', 'value'); + +// Output formatted XML +echo $xml->toString(format: true); +``` + +Output: +```xml + + + + text + more text + other text + + +``` + +## Documentation + +The library is fully documented with detailed guides and examples for each feature: + +- [Creating XML Documents](docs/using-api.md): Learn how to create and manipulate XML documents using the API +- [Working with Namespaces](docs/namespaces.md): Guide to handling XML namespaces properly +- [Querying with XPath](docs/query-document.md): How to use XPath expressions to query XML documents +- [PHP Models to XML](docs/convert-model-xml.md): Converting PHP objects to XML and vice versa +- [Attribute-Based Mapping](docs/convert-model-xml-withattributes.md): Using PHP attributes to control XML serialization +- [Cleaning Documents](docs/clean-document.md): Removing specific tags from XML documents +- [File Operations](docs/file-handling.md): Loading and saving XML from/to files +- [XML Validation](docs/validate-document.md): Validating XML documents against schemas + +## Installation ```bash composer require "byjg/xmlutil" ``` -## Running the Tests +## Running Tests ```bash vendor/bin/phpunit ``` +## License + +MIT + ## Dependencies ```mermaid @@ -38,6 +99,5 @@ flowchart TD byjg/xmlutil --> byjg/serializer ``` - ---- [Open source ByJG](http://opensource.byjg.com) \ No newline at end of file diff --git a/docs/convert-model-xml-withattributes.md b/docs/convert-model-xml-withattributes.md index 72213bc..9f50575 100644 --- a/docs/convert-model-xml-withattributes.md +++ b/docs/convert-model-xml-withattributes.md @@ -11,8 +11,8 @@ Example: getContents(); + +// Create an XmlDocument from the file +$xml = new XmlDocument($file); +``` + +## Saving a file + +```php +value'); +$xml->save('/path/to/file.xml'); + +// Or use the File class directly +$file = new File('/path/to/file.xml', true); +$file->save($xml->toString()); +``` + +## Getting the filename + +```php +getFilename(); +``` \ No newline at end of file diff --git a/docs/query-document.md b/docs/query-document.md index 4b2432b..12d7597 100644 --- a/docs/query-document.md +++ b/docs/query-document.md @@ -13,5 +13,5 @@ $node = $xml->selectSingleNode('//subnode'); ## Select all nodes based on XPath ```php -$nodeList = $xml->selectNodes($myNode, '//subnode'); +$nodeList = $xml->selectNodes('//subnode'); ``` diff --git a/docs/validate-document.md b/docs/validate-document.md new file mode 100644 index 0000000..aa11367 --- /dev/null +++ b/docs/validate-document.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 8 +--- + +# Validating XML Documents + +XmlUtil provides a way to validate XML documents against XSD schemas. + +## Validating an XML document + +```php +value'); + +// Validate against an XSD schema +try { + $xml->validate('/path/to/schema.xsd'); + echo "Document is valid!"; +} catch (\ByJG\XmlUtil\Exception\XmlUtilException $e) { + echo "Document is not valid: " . $e->getMessage(); +} +``` + +## Getting validation errors without throwing exceptions + +```php +value'); + +// Validate and get errors without throwing an exception +$errors = $xml->validate('/path/to/schema.xsd', false); + +if (empty($errors)) { + echo "Document is valid!"; +} else { + echo "Document is not valid:"; + foreach ($errors as $error) { + echo "- " . $error . "\n"; + } +} +``` \ No newline at end of file From c215897a2b7e75b5b767e719933ae2b8065b6af0 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Fri, 14 Mar 2025 08:23:31 -0500 Subject: [PATCH 4/6] Add #[Override] attribute to setUp method in CleanDocumentTest This change clarifies that the setUp method intentionally overrides a parent method. It improves code readability and ensures adherence to annotations for better maintenance. --- tests/CleanDocumentTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/CleanDocumentTest.php b/tests/CleanDocumentTest.php index 0c7be80..a3ae8a6 100644 --- a/tests/CleanDocumentTest.php +++ b/tests/CleanDocumentTest.php @@ -3,12 +3,14 @@ namespace Tests; use ByJG\XmlUtil\CleanDocument; +use Override; use PHPUnit\Framework\TestCase; class CleanDocumentTest extends TestCase { protected CleanDocument $object; + #[Override] public function setUp(): void { $this->object = new CleanDocument( From 8671122bdff8c0db017ae1ce4fd8583138c93c3a Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Fri, 21 Mar 2025 15:57:32 -0500 Subject: [PATCH 5/6] Update configs and dependencies for improved tooling Restored README formatting, added VSCode launch config for debugging, and adjusted PHPUnit and Psalm versions. Updated GitHub Actions workflow for consistent testing steps and aligned PHPUnit schema URL in config files. Removed unnecessary comments from FUNDING.yml. --- .github/FUNDING.yml | 2 -- .github/workflows/phpunit.yml | 2 +- .vscode/launch.json | 35 +++++++++++++++++++++++++++++++++++ README.md | 4 ++-- composer.json | 2 +- phpunit.xml.dist | 2 +- 6 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 3a9251f..ff81655 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1 @@ -# These are supported funding model platforms - github: byjg diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 9aa23c6..c2f2580 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -24,8 +24,8 @@ jobs: steps: - uses: actions/checkout@v4 - run: composer install - - run: ./vendor/bin/phpunit --stderr - run: ./vendor/bin/psalm + - run: ./vendor/bin/phpunit Documentation: if: github.ref == 'refs/heads/master' diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6bcabfb --- /dev/null +++ b/.vscode/launch.json @@ -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}" + } + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 35327ae..a9ac0ad 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# PHP XML Util - [![Build Status](https://github.com/byjg/php-xmlutil/actions/workflows/phpunit.yml/badge.svg?branch=master)](https://github.com/byjg/php-xmlutil/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-xmlutil/) [![GitHub license](https://img.shields.io/github/license/byjg/php-xmlutil.svg)](https://opensource.byjg.com/opensource/licensing.html) [![GitHub release](https://img.shields.io/github/release/byjg/php-xmlutil.svg)](https://github.com/byjg/php-xmlutil/releases/) +# PHP XML Util + A powerful and intuitive PHP library for working with XML documents. This utility makes XML manipulation, querying, and conversion simple and straightforward in PHP. diff --git a/composer.json b/composer.json index 68b7d51..e9d9545 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ }, "require-dev": { "phpunit/phpunit": "^10.5|^11.5", - "vimeo/psalm": "^6.0" + "vimeo/psalm": "^5.9|^6.2" }, "license": "MIT" } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 584610f..711a9b0 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -15,7 +15,7 @@ and open the template in the editor. displayDetailsOnTestsThatTriggerWarnings="true" displayDetailsOnPhpunitDeprecations="true" stopOnFailure="false" - xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"> From 9ce7cad619ee394d79d771cbed522a5568c60dc4 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Fri, 21 Mar 2025 16:10:57 -0500 Subject: [PATCH 6/6] Update documentation with additional XML utility features Enhance documentation for XmlUtil by adding examples and methods for querying, creating, and cleaning XML documents. Introduce advanced features such as namespace handling, node manipulation, content removal, and attribute mapping for improved control over XML processing. --- docs/clean-document.md | 70 ++++++++++- docs/convert-model-xml-withattributes.md | 56 +++++++-- docs/file-handling.md | 5 +- docs/query-document.md | 72 +++++++++++ docs/using-api.md | 151 +++++++++++++++++++++-- 5 files changed, 331 insertions(+), 23 deletions(-) diff --git a/docs/clean-document.md b/docs/clean-document.md index e85995e..8f07ce4 100644 --- a/docs/clean-document.md +++ b/docs/clean-document.md @@ -4,10 +4,9 @@ sidebar_position: 6 # Clean Document -XmlUtil have a class for selectively remove specific marks (tags) -from the document or remove all marks. +XmlUtil provides a dedicated `CleanDocument` class for selectively removing specific tags or content from XML or HTML documents. This is useful for cleaning up documents before processing or display. -Example: +## Basic Usage ```php stripTagsExcept(['img']) ->get(); ``` + +## Available Methods + +### stripAllTags() + +Removes all HTML/XML tags from the document. + +```php +$document = new \ByJG\XmlUtil\CleanDocument($html); +$plainText = $document->stripAllTags(); +``` + +### stripTagsExcept(array $allowedTags) + +Strips all HTML/XML tags except those specified in the array. + +```php +$document = new \ByJG\XmlUtil\CleanDocument($html); +$cleanHtml = $document->stripTagsExcept(['p', 'div', 'span'])->get(); +``` + +### removeContentByProperty(string $property) + +Removes content from any tag that contains the specified property. + +```php +$document = new \ByJG\XmlUtil\CleanDocument($html); +// Removes all tags containing the "style" property and their content +$cleanHtml = $document->removeContentByProperty('style')->get(); +``` + +### removeContentByTag(string $tag, string $property = '') + +Removes content from the specified tag, optionally filtering by a property. + +```php +$document = new \ByJG\XmlUtil\CleanDocument($html); +// Removes all