{"id":17042140,"url":"https://github.com/bluem/xmltransformer","last_synced_at":"2025-09-02T10:34:24.867Z","repository":{"id":2619585,"uuid":"3603983","full_name":"BlueM/XMLTransformer","owner":"BlueM","description":"Transforms XML (into XML, HTML, plaintext, …) using native PHP","archived":false,"fork":false,"pushed_at":"2024-10-27T14:48:18.000Z","size":98,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-10T07:16:22.178Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"adanvillarreal/TeserCats","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BlueM.png","metadata":{"files":{"readme":"README.markdown","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-03-02T16:43:33.000Z","updated_at":"2024-10-27T14:48:21.000Z","dependencies_parsed_at":"2022-08-21T03:40:24.480Z","dependency_job_id":null,"html_url":"https://github.com/BlueM/XMLTransformer","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlueM%2FXMLTransformer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlueM%2FXMLTransformer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlueM%2FXMLTransformer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlueM%2FXMLTransformer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BlueM","download_url":"https://codeload.github.com/BlueM/XMLTransformer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248583141,"owners_count":21128524,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T09:15:14.503Z","updated_at":"2025-04-12T14:42:19.180Z","avatar_url":"https://github.com/BlueM.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/BlueM/XMLTransformer.png)](https://travis-ci.org/BlueM/XMLTransformer)\n[![SensioLabsInsight](https://insight.sensiolabs.com/projects/3f1631ee-2286-4c0e-b21c-da192bb3efba/mini.png)](https://insight.sensiolabs.com/projects/3f1631ee-2286-4c0e-b21c-da192bb3efba)\n\nOverview\n========\nXMLTransformer is a PHP library for transforming any kind of input XML into an output string. This output string does not have to be XML, but can also be, for instance, HTML or plain text.\n\n\nTransformations\n---------------\nXMLTransformer is able to …\n\n* Remove tags, including or excluding the tag’s content\n* Rename attributes\n* Remove attributes\n* Add attributes\n* Change attributes’ values\n* Insert content before and after a tag\n* Insert content at the beginning or end of tag content\n* Transform a tag including all of its content by passing it to a user-defined closure\n* Perform any combination of the above\n* Modify the content of text nodes\n\nWhen to use\n-----------\nIn my opinion, XMLTransformer performs very well if the input XML and the output to be produced are similarly structured. Moreover, if data from the input XML has to be processed by an existing PHP codebase, it is possibly cleaner and simpler to use XMLTransformer instead of XSL-T.\n\nWhen not to use\n----------------------------\nWhen the input data has to be re-arranged, you are probably better off with XSL-T, as this is something that XMLTransformer does not provide. (Although to some extent it can be done with appropriate callback code.) Of course you are free to combine XSL-T with XMLTransformer to get the best of both worlds, if one is not enough.\n\n\nInstallation\n============\nThe recommended way to install this library is through [Composer](https://getcomposer.org). For this, add `\"bluem/xmltransformer\": \"~2.0\"` to the requirements in your `composer.json` file. As the library uses [semantic versioning](http://semver.org), you will get fixes and feature additions, but not changes which break the API.\n\nAlternatively, you can clone the repository using git or download an [archived release](https://github.com/BlueM/XMLTransformer/releases).\n\n\nUsage\n=====\nYou pass the input XML and the name of a callback function or a callback method (specified as usual, using `[$object, 'methodName']` syntax) or an anonymous function / closure to `XMLTransformer`.\n\nFor each tag (opening, closing or empty) the callback function will be called with the tag’s name, its attributes and information on whether it is an opening, empty or closing tag. Now, your function / method / closure can return one of three things:\n\n* An array (which describes what transformation(s) should be performed – see below)\n* `false` (meaning: discard this tag, its attributes as well as any tags and any child elements)\n* `null` (meaning: don’t modify anything – this is the default behaviour, i.e.: if the callback returns nothing, nothing is changed.\n\n\nCallback function arguments\n----------------------------\nThe callback function / method / closure is called with three arguments:\n\n* The element / tag name\n* The element / tag’s attributes (an associative array of name=\u003evalue pairs, where the name contains the namespace, if the attribute is not from the default namespace)\n* An element type constant, which will be `XMLTransformer::ELEMENT_OPEN` for an opening tag, `XMLTransformer::ELEMENT_EMPTY` for an empty tag and `XMLTransformer::ELEMENT_CLOSE` for a closing tag.\n\nPlease note that the attributes will *always* be given, even for a closing tag.\n\n\nThe transformation description array\n-------------------------------------\nWhen you wish to perform a transformation, you must return an associative array. In this case, the following keys can be used:\n\n* `XMLTransformer::RULE_TAG`: Returning false for key “tag” removes the tag (incl. its attributes, of course), but keeps any enclosed content. Returning a string will set the tag name to that string.\n* `XMLTransformer::RULE_ADD_BEFORE`: Will insert the given string before the opening tag\n* `XMLTransformer::RULE_ADD_AFTER`: Will insert the given string after the closing tag\n* `XMLTransformer::RULE_ADD_START`: Will insert the given string right after the opening tag\n* `XMLTransformer::RULE_ADD_END`: Will insert the given string right before the closing tag\n* `XMLTransformer::RULE_TRANSFORM_OUTER`: Value must be a closure, which will be passed the element itself incl. all its content as a string. The closure’s return value will replace the element.\n* `XMLTransformer::RULE_TRANSFORM_INNER`: Value must be a closure, which will be passed the element’s content as a string. The closure’s return value will replace the element.\n\nAdditionally, for handling attributes, array keys in the form of “@\u003cname\u003e” can be used, where \u003cname\u003e is the attribute name (with namespaces, if not from the default namespace). The value of such an array key can be one of:\n* false: The attribute will be removed\n* A string starting with “@”: The attribute will be renamed\n* A string: The attribute value will be set to this string.\n\nFor instance, this return array …\n\n```php\nreturn [\n    XMLTransformer::RULE_TAG =\u003e 'demo',\n    '@xml:id' =\u003e 'id',\n    '@foo' =\u003e false,\n    XMLTransformer::RULE_ADD_AFTER =\u003e '!',\n];\n```\n\n… means:\n\n* Rename the tag to “demo”\n* Rename the “xml:id” attribute to “id”\n* Remove the “@foo” attribute\n* Insert the string “!” after the closing tag (or directly after the tag, if it’s an empty tag)\n\nPlease note that (as `XMLTransformer` is not restricted to produce XML) no automatic escaping is done to values returned by the array. Only exception: attribute values, as XMLTransformer assumes that if you set attribute values, you want XML or HTML output.\n\n\nPassing attributes by reference\n--------------------------------\nThe callback can accept the arguments’ array by reference, therefore allowing direct manipulation of the attributes. This can be handy when changing or removing a large number of attributes or when only a prefix or suffix (or namespace) of attributes’ names is known in advance.\n\nSee below for an example.\n\n\nExamples\n===========\n\nAll of the examples below assume that your code includes the usual boilerplate code for Composer autoloading:\n\n```php\nrequire 'vendor/autoload.php';\n```\n\nHello world\n------------\n```php\nuse BlueM\\XMLTransformer;\n\necho XMLTransformer::transformString(\n    '\u003croot\u003e\u003celement\u003eHello world\u003c/element\u003e\u003c/root\u003e',\n    function($tag, $attributes, $opening) {\n        return [\n            XMLTransformer::RULE_TAG =\u003e false, // \u003c-- Removes tag, but keeps content\n        ];\n    }\n);\n// Result: “Hello World”.\n```\n\nMultilingual Hello world\n---------------------------\n```php\nuse BlueM\\XMLTransformer;\n\nfunction transform($tag, $attributes, $opening) {\n    if ('hello-world' == $tag) {\n        if (isset($attributes['xml:lang']) and\n            'de' == $attributes['xml:lang']) {\n            $str = 'Hallo Welt';\n        } else {\n            $str = 'Hello world';\n        }\n        return [\n            XMLTransformer::RULE_TAG =\u003e false, // \u003c-- Remove the tag, keep content\n            XMLTransformer::RULE_ADD_BEFORE =\u003e $str,  // \u003c- Insert literal content\n        ];\n    }\n\n    if ('root' == $tag) {\n        // We do not want the enclosing \u003croot\u003e tags in the output\n        return [XMLTransformer::RULE_TAG =\u003e false];\n    }\n}\n\necho XMLTransformer::transformString(\n    '\u003croot\u003e\u003chello-world xml:lang=\"de\" /\u003e\u003c/root\u003e',\n    'transform'\n);\n// Result: “Hallo Welt”\n\necho XMLTransformer::transformString(\n    '\u003croot\u003e\u003chello-world xml:lang=\"en\" /\u003e\u003c/root\u003e',\n    'transform'\n);\n// Result: “Hello world”\n```\n\nRemoving tags including all of their content\n--------------------------------------------\n```php\necho XMLTransformer::transformString(\n    '\u003croot\u003e\u003cremove\u003eHello \u003c/remove\u003eWorld\u003c/root\u003e',\n        function($tag, $attributes, $opening) {\n            switch ($tag) {\n                case 'remove':\n                    return false; // \u003c-- Removes tag incl. content\n                case 'root':\n                case 'keep':\n                    return [XMLTransformer::RULE_TAG =\u003e false]; // \u003c-- Remove tag, keep content\n                    break;\n                default:\n                    // Returning null is not necessary, as this\n                    // is the default behaviour. It is equivalent\n                    // to \"Do not change anything.\"\n                    return null;\n            }\n        }\n);\n// Result: “World”\n```\n\nChanging attribute values\n-------------------------\n```php\necho XMLTransformer::transformString(\n    '\u003croot abc=\"def\"\u003e\u003c/root\u003e',\n    function($tag, $attributes, $opening) {\n        return [\n            '@abc' =\u003e 'xyz'\n        ];\n    }\n);\n// Result: “\u003croot abc=\"xyz\"\u003e\u003c/root\u003e”\n// Please note that empty tags will always be returned with\n// a space before the slash.\n```\n\nAdding, renaming and removing attributes\n---------------------------------------\n```php\necho XMLTransformer::transformString(\n    '\u003croot xml:id=\"abc\"\u003e\u003cbla xml:id=\"def\" blah=\"yes\"/\u003e\u003c/root\u003e',\n    function($tag, $attributes, $opening) {\n        return [\n            '@foo' =\u003e 'bar', // Add attribute \"foo\" with value \"bar\"\n            '@blah' =\u003e false, // Remove attribute \"blah\"\n            '@xml:id' =\u003e '@id', // Rename attribute \"xml:id\" to \"id\"\n        ];\n    }\n);\n// Result: “\u003croot id=\"abc\" foo=\"bar\"\u003e\u003cbla id=\"def\" foo=\"bar\" /\u003e\u003c/root\u003e”\n// Please note that empty tags will always be returned with\n// a space before the slash.\n```\n\nModifying attributes by reference\n---------------------------------\n```php\necho XMLTransformer::transformString(\n    '\u003croot xml:a=\"a\" xml:b=\"b\" id=\"foo\"\u003eContent\u003c/root\u003e',\n    function($tag, \u0026$attributes, $opening) {\n        foreach ($attributes as $name =\u003e $value) {\n            if ('xml:' === substr($name, 0, 4)) {\n                unset($attributes[$name]); // Drop attributes in \"xml\" namespace\n            }\n        }\n    }\n);\n// Result: “\u003croot id=\"foo\"\u003eContent\u003c/root\u003e”\n```\n\n\nAuthor \u0026 License\n=========================\nThis code was written by Carsten Blüm ([www.bluem.net](http://www.bluem.net)) and licensed under the BSD2 license.\n\n\nVersion history\n===============\n\n## 2.0.1 (2020-12-02)\n* Fixes an inconsistent behavior in case `null` is returned as value for `XMLTransformer::RULE_TAG` (which is *not* supposed to be done).\n* Just for the record: tests run successfully on PHP8 (not yet in `.travis.yml`, as Travis CI does not support PHP 8 yet).\n\n## 2.0 (2018-02-12)\n* BC break: minimum PHP version is 7.0\n* BC break: introduced class constants for transformation rules which should be used instead of the magic strings used with version 1. This means, that in your code, you should …\n    * Change string `insend` to `XMLTransformer::RULE_ADD_END`\n    * Change string `insafter` to `XMLTransformer::RULE_ADD_AFTER`\n    * Change string `insbefore` to `XMLTransformer::RULE_ADD_BEFORE`\n    * Change string `insstart` to `XMLTransformer::RULE_ADD_START`\n    * Change string `transformInner` to `XMLTransformer::RULE_TRANSFORM_INNER`\n    * Change string `transformOuter` to `XMLTransformer::RULE_TRANSFORM_OUTER`\n    * Change string `tag` to `XMLTransformer::RULE_TAG`\n* BC break: constant `XMLTransformer::ELOPEN` was renamed to `XMLTransformer::ELEMENT_OPEN`, `XMLTransformer::ELEMPTY` was renamed to `XMLTransformer::ELEMENT_EMPTY` and `XMLTransformer::ELCLOSE` was renamed to `XMLTransformer::ELEMENT_CLOSE`.\n* Code simplification, modernization\n\n## 1.2 (2015-12-05)\n* Adds missing support for handling CDATA. By default, CDATA sections are retained, but by setting the third argument to `transformString()` to false, CDATA content is replaced with but as PCDATA content with `\u003c` and `\u003e` and `\u0026` escaped.\n\n## 1.1 (2015-08-15)\n* The callback function/method/closure can receive the attributes by reference. See “Passing attributes by reference” above.\n* Fix for PHP 5.3 compatibility\n\n## 1.0 (2012-12-12)\n* First public version\n*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluem%2Fxmltransformer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbluem%2Fxmltransformer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluem%2Fxmltransformer/lists"}