Bug #78352 [Com]: schemaValidate ignores namespaces dynamically added to a DOMDocument
| From: | subjective@php.net | Date: | Mon, 29 Jul 2019 20:56:25 +0000 |
| Subject: | Bug #78352 [Com]: schemaValidate ignores namespaces dynamically added to a DOMDocument | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-222008@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78352&edit=1
ID: 78352
Comment by: subjective@php.net
Reported by: fred5 at originsystems dot co dot za
Summary: schemaValidate ignores namespaces dynamically added
to a DOMDocument
Status: Open
Type: Bug
Package: DOM XML related
Operating System: CentOS 7
PHP Version: 7.3.7
Block user comment: N
Private report: N
New Comment:
You create the element with an non-namespace-aware method. That means that it does not know about
namespaces. Adding them as an attribute will not change the namespace of a node. You need to use
DOMDocument::createElementNS(). Adding the namespace definition as an attribute is not needed (it
will be added automatically):
Example:
--------
$dom = new DOMDocument();
$dom->appendChild($dom->createElementNS("http://purl.oclc.org/ooxml/wordprocessingml/main",
"w:document"));
Previous Comments:
------------------------------------------------------------------------
[2019-07-29 20:31:02] fred5 at originsystems dot co dot za
Description:
------------
When building an XML document node by node via DOMDdocument, the
DOMDocument::schemaValidate/Source() methods incorrectly ignore xmlns:... attributes, breaking the
validation.
However, if DOMDocument::loadXML($xml) is used to create the DOMDocument, then the xmlns:...
attributes are respected.
It is an elusive bug to identify when working with complex XML documents and schemas however I have
put together a very simple code sample illustrating the issue clearly.
This issue was identified here 10 years ago: https://www.php.net/manual/en/domdocument.schemavalidate.php#89893
and still persists.
Test script:
---------------
<?php
function printComment(string $text) : void {
print PHP_EOL . str_pad("-",5, "-") . " {$text} " . PHP_EOL;
}
$xsd = '<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://purl.oclc.org/ooxml/wordprocessingml/main"
targetNamespace="http://purl.oclc.org/ooxml/wordprocessingml/main"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="document"/>
</xs:schema>';
printComment("First, a super simple schema.");
print $xsd . PHP_EOL;
printComment("Now, let's use DOM to build an XML document that is valid for the
schema...");
$dom = new DOMDocument();
$dom->appendChild($dom->createElement("w:document"));
$dom->documentElement->setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:w","http://purl.oclc.org/ooxml/wordprocessingml/main");
printComment("Great, here's our created XML document. (with 'w:document'
referencing xmlns:w as desired)");
print $dom->saveXML();
printComment("Let's validate our new document against our schema...");
printComment(($dom->schemaValidateSource($xsd)?"Validation succeeded!":"Validation
failed. Oh dear, this is an unhappy suprise, the XML looks fine to me!"));
printComment("Now lets refresh our DOMDocument with a full reload of its own XML
content");
$dom->loadXML($dom->saveXML());
printComment("Let's try validating it again against our schema...");
printComment(($dom->schemaValidateSource($xsd)?"Validation succeeded. How is this possible,
nothing has changed in the XML!":"As expected we failed again - it's weird but at
least the behaviour is consistent."));
Expected result:
----------------
----- First, a super simple schema.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://purl.oclc.org/ooxml/wordprocessingml/main"
targetNamespace="http://purl.oclc.org/ooxml/wordprocessingml/main"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="document"/>
</xs:schema>
----- Now, let's use DOM to build an XML document that is valid for the schema...
----- Great, here's our created XML document. (with 'w:document' referencing xmlns:w
as desired)
<?xml version="1.0"?>
<w:document xmlns:w="http://purl.oclc.org/ooxml/wordprocessingml/main"/>
----- Let's validate our new document against our schema...
----- Validation succeeded!
----- Now lets refresh our DOMDocument with a full reload of its own XML content
----- Let's try validating it again against our schema...
----- Validation succeeded. How is this possible, nothing has changed in the XML!
Actual result:
--------------
----- First, a super simple schema.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://purl.oclc.org/ooxml/wordprocessingml/main"
targetNamespace="http://purl.oclc.org/ooxml/wordprocessingml/main"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="document"/>
</xs:schema>
----- Now, let's use DOM to build an XML document that is valid for the schema...
----- Great, here's our created XML document. (with 'w:document' referencing xmlns:w
as desired)
<?xml version="1.0"?>
<w:document xmlns:w="http://purl.oclc.org/ooxml/wordprocessingml/main"/>
----- Let's validate our new document against our schema...
Warning: DOMDocument::schemaValidateSource(): Element 'w:document': No matching global
declaration available for the validation root. in
C:\OriginSystems\Git\Test-me\DOCX_schemaValidate\validationError.php on line 24
----- Validation failed. Oh dear, this is an unhappy suprise, the XML looks fine to me!
----- Now lets refresh our DOMDocument with a full reload of its own XML content
----- Let's try validating it again against our schema...
----- Validation succeeded. How is this possible, nothing has changed in the XML!
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78352&edit=1