{"record":{"id":"039ffd95f9cd567a","repo":"PHPOffice/PHPWord","slug":"dom-needs-to-be-loaded-before-registering-a-namespace","errorCode":null,"errorMessage":"Dom needs to be loaded before registering a namespace","messagePattern":"Dom needs to be loaded before registering a namespace","errorType":"validation","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/PhpWord/Shared/XMLReader.php","lineNumber":137,"sourceCode":"        }\n\n        $result = @$this->xpath->query($path, $contextNode);\n\n        return empty($result) ? new DOMNodeList() : $result; // @phpstan-ignore-line\n    }\n\n    /**\n     * Registers the namespace with the DOMXPath object.\n     *\n     * @param string $prefix The prefix\n     * @param string $namespaceURI The URI of the namespace\n     *\n     * @return bool true on success or false on failure\n     */\n    public function registerNamespace($prefix, $namespaceURI)\n    {\n        if ($this->dom === null) {\n            throw new InvalidArgumentException('Dom needs to be loaded before registering a namespace');\n        }\n        if ($this->xpath === null) {\n            $this->xpath = new DOMXpath($this->dom);\n        }\n\n        return $this->xpath->registerNamespace($prefix, $namespaceURI);\n    }\n\n    /**\n     * Get element.\n     *\n     * @param string $path\n     *\n     * @return null|DOMElement\n     */\n    public function getElement($path, ?DOMElement $contextNode = null)\n    {\n        $elements = $this->getElements($path, $contextNode);","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/PHPOffice/PHPWord/blob/aef95c04151b5633cc505f672ddd6a71da900ee1/src/PhpWord/Shared/XMLReader.php#L119-L155","documentation":"XMLReader wraps a DOMDocument and an optional DOMXpath. registerNamespace() requires that a document has already been loaded (via getDomFromZip/getDomFromXML), because the namespace is registered on the xpath object built from that DOM. If $this->dom is still null, InvalidArgumentException is thrown to prevent calling registerNamespace on nothing.","triggerScenarios":"Calling registerNamespace($prefix,$uri) on a fresh XMLReader instance before any read/getDomFromZip/getDomFromXML call has populated $this->dom.","commonSituations":"Setting up namespace prefixes in constructor/initialization code before loading the document; reusing a reader object across requests after state reset; misunderstanding the required load-then-register order.","solutions":["Load the document first (getDomFromZip or getDomFromXML), then call registerNamespace.","Move registerNamespace calls to after the load step in your setup code.","If reusing a reader, ensure it still holds its DOM (it was not recreated) before registering.","Note: for default/unknown namespaces you may instead use registerXPathNamespace on evaluated nodes."],"exampleFix":"// before\n$reader = new XMLReader();\n$reader->registerNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');\n// after\n$reader = new XMLReader();\n$reader->getDomFromZip('doc.docx', 'word/document.xml');\n$reader->registerNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');","handlingStrategy":"type-guard","validationCode":"$doc = new \\ReflectionProperty($reader, 'dom');\n$doc->setAccessible(true);\nif ($doc->getValue($reader) === null) {\n    throw new LogicException('Call getDomFromZip/getDomFromXML before registerNamespace');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $reader->registerNamespace($prefix, $uri);\n} catch (\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'Dom needs to be loaded')) {\n        $reader->getDomFromZip($zipFile, $xmlFile);\n        $reader->registerNamespace($prefix, $uri);\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Enforce load-then-query ordering in a wrapper class or factory method","Never configure namespaces in a constructor before loading the document","Reuse the same reader instance without recreating it mid-flow"],"tags":["phpword","dom","xpath","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"aef95c04151b5633cc505f672ddd6a71da900ee1","analyzedAt":"2026-09-14T10:53:58.933Z","contentChangedAt":"2026-09-14T10:53:58.933Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}