{"id":22764611,"url":"https://github.com/kuria/dom","last_synced_at":"2025-09-22T03:57:18.990Z","repository":{"id":22774627,"uuid":"26120636","full_name":"kuria/dom","owner":"kuria","description":"Wrappers around the PHP DOM classes","archived":false,"fork":false,"pushed_at":"2023-04-22T14:38:48.000Z","size":80,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-14T23:13:36.856Z","etag":null,"topics":["document-object-model","dom","domdocument","html","php","wrapper","xml","xpath"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kuria.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-11-03T13:53:50.000Z","updated_at":"2023-09-19T17:45:22.000Z","dependencies_parsed_at":"2024-12-11T12:19:35.698Z","dependency_job_id":null,"html_url":"https://github.com/kuria/dom","commit_stats":{"total_commits":49,"total_committers":2,"mean_commits":24.5,"dds":"0.020408163265306145","last_synced_commit":"6338834423f84ddf526b8be71f943b0b97de1fcb"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/kuria/dom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuria%2Fdom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuria%2Fdom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuria%2Fdom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuria%2Fdom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kuria","download_url":"https://codeload.github.com/kuria/dom/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuria%2Fdom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274609465,"owners_count":25316621,"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","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["document-object-model","dom","domdocument","html","php","wrapper","xml","xpath"],"created_at":"2024-12-11T12:09:29.154Z","updated_at":"2025-09-22T03:57:17.798Z","avatar_url":"https://github.com/kuria.png","language":"PHP","readme":"DOM\n###\n\nWrappers around the `PHP DOM classes \u003chttp://php.net/manual/en/book.dom.php\u003e`__\nthat handle the common DOM extension pitfalls.\n\n.. image:: https://travis-ci.com/kuria/dom.svg?branch=master\n   :target: https://travis-ci.com/kuria/dom\n\n.. contents::\n\n\nFeatures\n********\n\n- HTML documents\n\n  - encoding sniffing\n  - optional tidy support (automatically fix broken HTML)\n\n- HTML fragments\n- XML documents\n- XML fragments\n\n- XPath queries\n- creating documents from scratch\n- optional error suppression\n- helper methods for common tasks, such as:\n\n  - querying multiple or a single node\n  - checking for containment\n  - removing a node\n  - removing all nodes from a list\n  - prepending a child node\n  - inserting a node after another node\n  - fetching ``\u003chead\u003e`` and ``\u003cbody\u003e`` elements (HTML)\n  - fetching root elements  (XML)\n\n\nRequirements\n************\n\n- PHP 7.1+\n\n\nContainer methods\n*****************\n\nThese methods are shared by both HTML and XML containers.\n\n\nLoading documents\n=================\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\HtmlDocument; // or XmlDocument, HtmlFragment, etc.\n\n   // using loadString()\n   $dom = new HtmlDocument();\n   $dom-\u003esetLibxmlFlags($customLibxmlFlags); // optional\n   $dom-\u003esetIgnoreErrors($ignoreErrors); // optional\n   $dom-\u003eloadString($html);\n\n   // using static loadString() shortcut\n   $dom = HtmlDocument::fromString($html);\n\n   // using existing document instance\n   $dom = new HtmlDocument();\n   $dom-\u003eloadDocument($document);\n\n   // using static loadDocument() shortcut\n   $dom = HtmlDocument::fromDocument($document);\n\n   // creating an empty document\n   $dom = new HtmlDocument();\n   $dom-\u003eloadEmpty();\n\n\nGetting or changing document encoding\n=====================================\n\n.. code:: php\n\n   \u003c?php\n\n   // get encoding\n   $encoding = $dom-\u003egetEncoding();\n\n   // set encoding\n   $dom-\u003esetEncoding($newEncoding);\n\n.. NOTE::\n\n   The DOM extension uses UTF-8 encoding.\n\n   This means that text nodes, attributes, etc.:\n\n   - will be encoded using UTF-8 when read (e.g. ``$elem-\u003etextContent``)\n   - should be encoded using UTF-8 when written (e.g. ``$elem-\u003esetAttribute()``)\n\n   The encoding configured by ``setEncoding()`` is used when saving the document,\n   see `Saving documents`_.\n\n\nSaving documents\n================\n\n.. code:: php\n\n   \u003c?php\n\n   // entire document\n   $content = $dom-\u003esave();\n\n   // single element\n   $content = $dom-\u003esave($elem);\n\n   // children of a single element\n   $content = $dom-\u003esave($elem, true);\n\n\nGetting DOM instances\n=====================\n\nAfter a document has been loaded, the DOM instances are available via getters:\n\n.. code:: php\n\n   \u003c?php\n\n   $document = $dom-\u003egetDocument();\n   $xpath = $dom-\u003egetXpath();\n\n\nRunning XPath queries\n=====================\n\n.. code:: php\n\n   \u003c?php\n\n   // get a DOMNodeList\n   $divs = $dom-\u003equery('//div');\n\n   // get a single DOMNode (or null)\n   $div = $dom-\u003equery('//div');\n\n   // check if a query matches\n   $divExists = $dom-\u003eexists('//div');\n\n\nEscaping strings\n================\n\n.. code:: php\n\n   \u003c?php\n\n   $escapedString = $dom-\u003eescape($string);\n\n\nDOM manipulation and traversal helpers\n======================================\n\nHelpers for commonly needed tasks that aren't easily achieved via existing\nDOM methods:\n\n.. code:: php\n\n   \u003c?php\n\n   // check if the document contains a node\n   $hasNode = $dom-\u003econtains($node);\n\n   // check if a node contains another node\n   $hasNode = $dom-\u003econtains($node, $parentNode);\n\n   // remove a node\n   $dom-\u003eremove($node);\n\n   // remove a list of nodes\n   $dom-\u003eremoveAll($nodes);\n\n   // prepend a child node\n   $dom-\u003eprependChild($newNode, $existingNode);\n\n   // insert a node after another node\n   $dom-\u003einsertAfter($newNode, $existingNode);\n\n\nUsage examples\n**************\n\nHTML documents\n==============\n\nLoading an existing document\n----------------------------\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\HtmlDocument;\n\n   $html = \u003c\u003c\u003cHTML\n   \u003c!doctype html\u003e\n   \u003chtml\u003e\n       \u003chead\u003e\n           \u003cmeta charset=\"UTF-8\"\u003e\n           \u003ctitle\u003eExample document\u003c/title\u003e\n       \u003c/head\u003e\n       \u003cbody\u003e\n           \u003ch1\u003eHello world!\u003c/h1\u003e\n       \u003c/body\u003e\n   \u003c/html\u003e\n   HTML;\n\n   $dom = HtmlDocument::fromString($html);\n\n   var_dump($dom-\u003equeryOne('//title')-\u003etextContent);\n   var_dump($dom-\u003equeryOne('//h1')-\u003etextContent);\n\nOutput:\n\n::\n\n  string(16) \"Example document\"\n  string(12) \"Hello world!\"\n\n\nOptionally, the markup can be fixed by `Tidy \u003chttp://php.net/manual/en/book.tidy.php\u003e`_\nprior to being loaded.\n\n.. code:: php\n\n   \u003c?php\n\n   $dom = new HtmlDocument();\n   $dom-\u003esetTidyEnabled(true);\n   $dom-\u003eloadString($html);\n\n.. NOTE::\n\n   HTML documents ignore errors by default, so there is no need to call\n   ``$dom-\u003esetIgnoreErrors(true)``.\n\n\nCreating an new document\n------------------------\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\HtmlDocument;\n\n   // initialize empty document\n   $dom = new HtmlDocument();\n   $dom-\u003eloadEmpty(['formatOutput' =\u003e true]);\n\n   // add \u003ctitle\u003e\n   $title = $dom-\u003egetDocument()-\u003ecreateElement('title');\n   $title-\u003etextContent = 'Lorem ipsum';\n\n   $dom-\u003egetHead()-\u003eappendChild($title);\n\n   // save\n   echo $dom-\u003esave();\n\nOutput:\n\n::\n\n  \u003c!DOCTYPE html\u003e\n  \u003chtml\u003e\n  \u003chead\u003e\n  \u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"\u003e\n  \u003ctitle\u003eLorem ipsum\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n      \u003c/body\u003e\n  \u003c/html\u003e\n\n\nHTML fragments\n==============\n\nLoading an existing fragment\n----------------------------\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\HtmlFragment;\n\n   $dom = HtmlFragment::fromString('\u003cdiv id=\"test\"\u003e\u003cspan\u003eHello\u003c/span\u003e\u003c/div\u003e');\n\n   $element = $dom-\u003equeryOne('/div[@id=\"test\"]/span');\n\n   if ($element) {\n       var_dump($element-\u003etextContent);\n   }\n\nOutput:\n\n::\n\n  string(5) \"Hello\"\n\n.. NOTE::\n\n   HTML fragments ignore errors by default, so there is no need to call\n   ``$dom-\u003esetIgnoreErrors(true)``.\n\n\nCreating a new fragment\n-----------------------\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\HtmlFragment;\n\n   // initialize empty fragment\n   $dom = new HtmlFragment();\n   $dom-\u003eloadEmpty(['formatOutput' =\u003e true]);\n\n   // add \u003ca\u003e\n   $link = $dom-\u003egetDocument()-\u003ecreateElement('a');\n   $link-\u003esetAttribute('href', 'http://example.com/');\n   $link-\u003etextContent = 'example';\n\n   $dom-\u003egetBody()-\u003eappendChild($link);\n\n   // save\n   echo $dom-\u003esave();\n\nOutput:\n\n::\n\n  \u003ca href=\"http://example.com/\"\u003eexample\u003c/a\u003e\n\n\nXML documents\n=============\n\nLoading an existing document\n----------------------------\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\XmlDocument;\n\n   $xml = \u003c\u003c\u003cXML\n   \u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n   \u003clibrary\u003e\n       \u003cbook name=\"Don Quixote\" author=\"Miguel de Cervantes\" /\u003e\n       \u003cbook name=\"Hamlet\" author=\"William Shakespeare\" /\u003e\n       \u003cbook name=\"Alice's Adventures in Wonderland\" author=\"Lewis Carroll\" /\u003e\n   \u003c/library\u003e\n   XML;\n\n   $dom = XmlDocument::fromString($xml);\n\n   foreach ($dom-\u003equery('/library/book') as $book) {\n      /** @var \\DOMElement $book */\n      var_dump(\"{$book-\u003egetAttribute('name')} by {$book-\u003egetAttribute('author')}\");\n   }\n\nOutput:\n\n::\n\n  string(34) \"Don Quixote by Miguel de Cervantes\"\n  string(29) \"Hamlet by William Shakespeare\"\n  string(49) \"Alice's Adventures in Wonderland by Lewis Carroll\"\n\n\nCreating a new document\n-----------------------\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\XmlDocument;\n\n   // initialize empty document\n   $dom = new XmlDocument();\n   $dom-\u003eloadEmpty(['formatOutput' =\u003e true]);\n\n   // add \u003cusers\u003e\n   $document = $dom-\u003egetDocument();\n   $document-\u003eappendChild($document-\u003ecreateElement('users'));\n\n   // add some users\n   $bob = $document-\u003ecreateElement('user');\n   $bob-\u003esetAttribute('username', 'bob');\n   $bob-\u003esetAttribute('access-token', '123456');\n\n   $john = $document-\u003ecreateElement('user');\n   $john-\u003esetAttribute('username', 'john');\n   $john-\u003esetAttribute('access-token', 'foobar');\n\n   $dom-\u003egetRoot()-\u003eappendChild($bob);\n   $dom-\u003egetRoot()-\u003eappendChild($john);\n\n   // save\n   echo $dom-\u003esave();\n\nOutput:\n\n::\n\n  \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n  \u003cusers\u003e\n    \u003cuser username=\"bob\" access-token=\"123456\"/\u003e\n    \u003cuser username=\"john\" access-token=\"foobar\"/\u003e\n  \u003c/users\u003e\n\n\nHandling XML namespaces in XPath queries\n----------------------------------------\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\XmlDocument;\n\n   $xml = \u003c\u003c\u003cXML\n   \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n   \u003clib:root xmlns:lib=\"http://example.com/\"\u003e\n       \u003clib:book name=\"Don Quixote\" author=\"Miguel de Cervantes\" /\u003e\n       \u003clib:book name=\"Hamlet\" author=\"William Shakespeare\" /\u003e\n       \u003clib:book name=\"Alice's Adventures in Wonderland\" author=\"Lewis Carroll\" /\u003e\n   \u003c/lib:root\u003e\n   XML;\n\n   $dom = XmlDocument::fromString($xml);\n\n   // register namespace in XPath\n   $dom-\u003egetXpath()-\u003eregisterNamespace('lib', 'http://example.com/');\n\n   // query using the prefix\n   foreach ($dom-\u003equery('//lib:book') as $book) {\n       /** @var \\DOMElement $book */\n       var_dump($book-\u003egetAttribute('name'));\n   }\n\nOutput:\n\n::\n\n  string(11) \"Don Quixote\"\n  string(6) \"Hamlet\"\n  string(32) \"Alice's Adventures in Wonderland\"\n\n\nXML fragments\n=============\n\nLoading an existing fragment\n----------------------------\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\XmlFragment;\n\n   $dom = XmlFragment::fromString('\u003cfruits\u003e\u003cfruit name=\"Apple\" /\u003e\u003cfruit name=\"Banana\" /\u003e\u003c/fruits\u003e');\n\n   foreach ($dom-\u003equery('/fruits/fruit') as $fruit) {\n       /** @var \\DOMElement $fruit */\n       var_dump($fruit-\u003egetAttribute('name'));\n   }\n\nOutput:\n\n::\n\n  string(5) \"Apple\"\n  string(6) \"Banana\"\n\n\nCreating a new fragment\n-----------------------\n\n.. code:: php\n\n   \u003c?php\n\n   use Kuria\\Dom\\XmlFragment;\n\n   // initialize empty fragment\n   $dom = new XmlFragment();\n   $dom-\u003eloadEmpty(['formatOutput' =\u003e true]);\n\n   // add a new element\n   $person = $dom-\u003egetDocument()-\u003ecreateElement('person');\n   $person-\u003esetAttribute('name', 'John Smith');\n\n   $dom-\u003egetRoot()-\u003eappendChild($person);\n\n   // save\n   echo $dom-\u003esave();\n\nOutput:\n\n::\n\n  \u003cperson name=\"John Smith\"/\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkuria%2Fdom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkuria%2Fdom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkuria%2Fdom/lists"}