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
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
36 - 17 = ?
Subscribe to this entry?

 
 [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

Add a Patch

Pull Requests

Add a Pull Request

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-2020 The PHP Group
All rights reserved.
Last updated: Mon Oct 26 14:01:26 2020 UTC