php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78352 schemaValidate ignores namespaces dynamically added to a DOMDocument
Submitted: 2019-07-29 20:31 UTC Modified: 2019-07-30 10:32 UTC
From: fred5 at originsystems dot co dot za Assigned:
Status: Not a bug Package: DOM XML related
PHP Version: 7.3.7 OS: CentOS 7
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: fred5 at originsystems dot co dot za
New email:
PHP Version: OS:

 

 [2019-07-29 20:31 UTC] 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!  


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-07-29 20:56 UTC] subjective@php.net
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"));
 [2019-07-29 20:59 UTC] subjective@php.net
-Status: Open +Status: Not a bug
 [2019-07-29 20:59 UTC] subjective@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 [2019-07-30 10:32 UTC] fred5 at originsystems dot co dot za
I have tested and it is working perfectly.

My apologies and "Thank you"!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 02 17:01:35 2024 UTC