From b85786bdb434bfc46d6c72a92aaf0e68a36eef37 Mon Sep 17 00:00:00 2001
From: Alberto Massari <amassari@apache.org>
Date: Thu, 13 Aug 2009 11:11:08 +0000
Subject: [PATCH] When the xsi:type attribute is present, don't emit validation
 errors complaining of a missing declaration (XERCESC-1481)

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@803844 13f79535-47bb-0310-9956-ffa450edef68
---
 src/xercesc/internal/IGXMLScanner.cpp         | 25 +++++++++++--------
 src/xercesc/internal/SGXMLScanner.cpp         | 23 ++++++++++-------
 src/xercesc/internal/XSAXMLScanner.cpp        | 10 +++++---
 .../validators/schema/SchemaValidator.hpp     |  6 +++++
 4 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/src/xercesc/internal/IGXMLScanner.cpp b/src/xercesc/internal/IGXMLScanner.cpp
index 7851f2759..4f51fa247 100644
--- a/src/xercesc/internal/IGXMLScanner.cpp
+++ b/src/xercesc/internal/IGXMLScanner.cpp
@@ -2402,6 +2402,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
 
     //  We do something different here according to whether we found the
     //  element or not.
+    bool bXsiTypeSet= (fValidator && fGrammarType == Grammar::SchemaGrammarType)?((SchemaValidator*)fValidator)->getIsXsiTypeSet():false;
     if (wasAdded)
     {
         if (laxThisOne) {
@@ -2416,15 +2417,19 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
             // faulted-in, was not an element in the grammar pool originally
             elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
 
-            fValidator->emitError
-            (
-                XMLValid::ElementNotDefined
-                , elemDecl->getFullName()
-            );
-
-            if(fGrammarType == Grammar::SchemaGrammarType)
+            // xsi:type was specified, don't complain about missing definition
+            if(!bXsiTypeSet)
             {
-                fPSVIElemContext.fErrorOccurred = true;
+                fValidator->emitError
+                (
+                    XMLValid::ElementNotDefined
+                    , elemDecl->getFullName()
+                );
+
+                if(fGrammarType == Grammar::SchemaGrammarType)
+                {
+                    fPSVIElemContext.fErrorOccurred = true;
+                }
             }
         }
     }
@@ -2433,7 +2438,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
         // If its not marked declared and validating, then emit an error
         if (!elemDecl->isDeclared()) {
             if(elemDecl->getCreateReason() == XMLElementDecl::NoReason) {
-                if(fGrammarType == Grammar::SchemaGrammarType) {
+                if(!bXsiTypeSet && fGrammarType == Grammar::SchemaGrammarType) {
                     fPSVIElemContext.fErrorOccurred = true;
                 }
             }
@@ -2442,7 +2447,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                 fValidate = false;
                 fElemStack.setValidationFlag(fValidate);
             }
-            else if (fValidate)
+            else if (fValidate && !bXsiTypeSet)
             {
                 fValidator->emitError
                 (
diff --git a/src/xercesc/internal/SGXMLScanner.cpp b/src/xercesc/internal/SGXMLScanner.cpp
index 4155466de..28985ecb9 100644
--- a/src/xercesc/internal/SGXMLScanner.cpp
+++ b/src/xercesc/internal/SGXMLScanner.cpp
@@ -1423,6 +1423,7 @@ bool SGXMLScanner::scanStartTag(bool& gotData)
 
     //  We do something different here according to whether we found the
     //  element or not.
+    bool bXsiTypeSet= (fValidator)?((SchemaValidator*)fValidator)->getIsXsiTypeSet():false;
     if (wasAdded)
     {
         if (laxThisOne) {
@@ -1437,12 +1438,15 @@ bool SGXMLScanner::scanStartTag(bool& gotData)
             // faulted-in, was not an element in the grammar pool originally
             elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
 
-            fValidator->emitError
-            (
-                XMLValid::ElementNotDefined
-                , elemDecl->getFullName()
-            );
-            fPSVIElemContext.fErrorOccurred = true;
+            if(!bXsiTypeSet)
+            {
+                fValidator->emitError
+                (
+                    XMLValid::ElementNotDefined
+                    , elemDecl->getFullName()
+                );
+                fPSVIElemContext.fErrorOccurred = true;
+            }
         }
     }
     else
@@ -1450,15 +1454,16 @@ bool SGXMLScanner::scanStartTag(bool& gotData)
         // If its not marked declared and validating, then emit an error
         if (!elemDecl->isDeclared()) {
             if(elemDecl->getCreateReason() == XMLElementDecl::NoReason) {
-                fPSVIElemContext.fErrorOccurred = true;
+                if(!bXsiTypeSet)
+                    fPSVIElemContext.fErrorOccurred = true;
             }
             if (laxThisOne) {
                 fValidate = false;
                 fElemStack.setValidationFlag(fValidate);
             }
 
-            if (fValidate)
-                {
+            if (fValidate && !bXsiTypeSet)
+            {
                 fValidator->emitError
                 (
                     XMLValid::ElementNotDefined
diff --git a/src/xercesc/internal/XSAXMLScanner.cpp b/src/xercesc/internal/XSAXMLScanner.cpp
index 18baf134c..fa50e496c 100644
--- a/src/xercesc/internal/XSAXMLScanner.cpp
+++ b/src/xercesc/internal/XSAXMLScanner.cpp
@@ -343,6 +343,7 @@ bool XSAXMLScanner::scanStartTag(bool& gotData)
 
     //  We do something different here according to whether we found the
     //  element or not.
+    bool bXsiTypeSet= (fValidator)?((SchemaValidator*)fValidator)->getIsXsiTypeSet():false;
     if (wasAdded || !elemDecl->isDeclared())
     {
         if (laxThisOne) {
@@ -357,10 +358,11 @@ bool XSAXMLScanner::scanStartTag(bool& gotData)
             // faulted-in, was not an element in the grammar pool originally
             elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
 
-            fValidator->emitError
-            (
-                XMLValid::ElementNotDefined, elemDecl->getFullName()
-            );
+            if(!bXsiTypeSet)
+                fValidator->emitError
+                (
+                    XMLValid::ElementNotDefined, elemDecl->getFullName()
+                );
         }
     }
 
diff --git a/src/xercesc/validators/schema/SchemaValidator.hpp b/src/xercesc/validators/schema/SchemaValidator.hpp
index 27df0edea..d209583f2 100644
--- a/src/xercesc/validators/schema/SchemaValidator.hpp
+++ b/src/xercesc/validators/schema/SchemaValidator.hpp
@@ -134,6 +134,7 @@ public:
     DatatypeValidator *getMostRecentAttrValidator() const;
     bool getErrorOccurred() const;
     bool getIsElemSpecified() const;
+    bool getIsXsiTypeSet() const;
     const XMLCh* getNormalizedValue() const;
 
 private:
@@ -422,6 +423,11 @@ inline const XMLCh* SchemaValidator::getNormalizedValue() const
     return fDatatypeBuffer.getRawBuffer();
 }
 
+inline bool SchemaValidator::getIsXsiTypeSet() const
+{
+    return (fXsiType!=0);
+}
+
 XERCES_CPP_NAMESPACE_END
 
 #endif
-- 
GitLab