Uploaded image for project: 'Xerces-C++'
  1. Xerces-C++
  2. XERCESC-2232

xsi:nil="false" fails validation for child elements

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Duplicate
    • 3.2.3
    • None
    • None

    Description

      We have recently found an issue with xsi:nil="false"

      Running the following code (also attached):

      #include <iostream>
      #include <string>
      #include <xercesc/dom/DOMException.hpp>
      #include <xercesc/framework/MemBufInputSource.hpp>
      #include <xercesc/parsers/XercesDOMParser.hpp>
      #include <xercesc/sax/ErrorHandler.hpp>
      #include <xercesc/sax/SAXParseException.hpp>
      
      namespace
      {
          class XMLValidatorErrorHandler : public xercesc::ErrorHandler
          {
          public:
              void warning(const xercesc::SAXParseException &e) final
              {
                  std::cerr << "Warning at file "
                            << xercesc::XMLString::transcode(e.getSystemId())
                            << ", line " << e.getLineNumber() << ", char "
                            << e.getColumnNumber() << ".  Message: "
                            << xercesc::XMLString::transcode(e.getMessage()) << "\n";
              }
      
              void error(const xercesc::SAXParseException &e) final
              {
                  std::cerr << "Error at file "
                            << xercesc::XMLString::transcode(e.getSystemId())
                            << ", line " << e.getLineNumber() << ", char "
                            << e.getColumnNumber() << ".  Message: "
                            << xercesc::XMLString::transcode(e.getMessage()) << "\n";
              }
      
              void fatalError(const xercesc::SAXParseException &e) final
              {
                  std::cerr << "Fatal Error at file "
                            << xercesc::XMLString::transcode(e.getSystemId())
                            << ", line " << e.getLineNumber() << ", char "
                            << e.getColumnNumber() << ".  Message: "
                            << xercesc::XMLString::transcode(e.getMessage()) << "\n";
              }
      
              void resetErrors() final
              {
              }
          };
      } // namespace
      
      int
      main(int argc, char **argv)
      {
          static_cast<void>(argc);
          static_cast<void>(argv);
      
          xercesc::XMLPlatformUtils::Initialize();
      
          std::string inputXml(
              "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
              "<ns1:NillableElement"
              "    xmlns:ns1=\"http://example.com/Nillable\"\n"
              "    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
              "    xsi:schemaLocation=\"http://example.com/Nillable Nillable.xsd\"\n"
              "    xsi:nil=\"false\">\n"
              "  <ns1:Val1>v1</ns1:Val1>\n"
              "</ns1:NillableElement>\n");
      
          std::string inputSchema(
              "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
              "<xs:schema"
              "    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n"
              "    xmlns:tns=\"http://example.com/Nillable\"\n"
              "    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
              "    targetNamespace=\"http://exampl.com/Nillable\"\n"
              "    elementFormDefault=\"qualified\">\n"
              "  <xs:complexType name=\"TestType\">\n"
              "    <xs:sequence>\n"
              "      <xs:element name=\"Val1\" type=\"xs:string\"/>\n"
              "    </xs:sequence>\n"
              "  </xs:complexType>\n"
              "  <xs:element name=\"NillableElement\" type=\"tns:TestType\" "
              "nillable=\"true\"/>\n"
              "  <xs:element name=\"NonNillableElement\" type=\"tns:TestType\" "
              "nillable=\"false\"/>\n"
              "</xs:schema>\n");
      
          xercesc::XercesDOMParser parser;
          parser.setValidationScheme(xercesc::XercesDOMParser::Val_Always);
          parser.setDoNamespaces(true);
          parser.setDoSchema(true);
          parser.setValidationSchemaFullChecking(true);
          parser.cacheGrammarFromParse(true);
          parser.useCachedGrammarInParse(true);
      
          XMLValidatorErrorHandler errorHandler;
          parser.setErrorHandler(&errorHandler);
      
          try {
              // Get Schema Input Source
              xercesc::MemBufInputSource schemaInputSource(
                  reinterpret_cast<const XMLByte *>(inputSchema.c_str()),
                  static_cast<XMLSize_t>(inputSchema.size()),
                  "schema");
              parser.loadGrammar(
                  schemaInputSource, xercesc::Grammar::SchemaGrammarType, true);
          }
          catch (const xercesc::XMLException &e) {
              std::cerr << "Fatal Error during schema parsing: "
                        << xercesc::XMLString::transcode(e.getMessage()) << "\n";
              return EXIT_FAILURE;
          }
          catch (const xercesc::DOMException &e) {
              std::cerr << "Fatal Error during schema parsing: "
                        << xercesc::XMLString::transcode(e.getMessage()) << "\n";
              return EXIT_FAILURE;
          }
      
          // Validate the XML against the Schema.
          try {
              // Get XML Input Source
              xercesc::MemBufInputSource xmlInputSource(
                  reinterpret_cast<const XMLByte *>(inputXml.c_str()),
                  static_cast<XMLSize_t>(inputXml.size()),
                  "xml");
              parser.parse(xmlInputSource);
          }
          catch (const xercesc::XMLException &e) {
              std::cerr << "Fatal Error during xml parsing: "
                        << xercesc::XMLString::transcode(e.getMessage()) << "\n";
              return EXIT_FAILURE;
          }
          catch (const xercesc::DOMException &e) {
              std::cerr << "Fatal Error during xml parsing: "
                        << xercesc::XMLString::transcode(e.getMessage()) << "\n";
              return EXIT_FAILURE;
          }
      
          return EXIT_SUCCESS;
      }
       

      returns the following validation error:

      Error at file xml, line 6, char 13.  Message: 'xsi:nil' specified for non-nillable element 'Val1' 

      But:

      • Only the NillableElement is marked as nillable in the schema, not Val1.
      • Only NillableElement element is marked as xsi:nil="false" in the xml, not Val1.
      • xsi:nil is not specified for Val1

      Attachments

        1. main.cxx
          5 kB
          Alan Howells

        Issue Links

          Activity

            People

              Unassigned Unassigned
              Howells Alan Howells
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: