错误 "different target namespace",但模式验证和名称空间匹配?

Error "different target namespace", but schema validates and namespaces match?

我有一个 XSD 和几个不同的 XML 消息从客户端发送到服务器,服务器试图使用模式验证消息。我正在使用 Xerces 进行解析。 XSD 和 XML 都是有效的,我 运行 通过几个工具 (for example) 来验证 XML 是否使用该模式进行了验证。

然而,当我运行这个程序时,它打印出:

Parsing Error: Schema in /path/to/xsd/MySchema.xsd has a different target namespace from the one specified in the instance document .

(该路径是架构的正确位置,因此它正在按预期读取文件。)我对名称空间了解不多,因此我尽量简化。这是 XSD 文件:

<xs:schema
        xmlns="http://www.mywebsite.com/schema/myschema"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        elementFormDefault="qualified"
        attributeFormDefault="unqualified"
        targetNamespace="http://www.mywebsite.com/schema/myschema">
    <xs:element name="My_Data">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="PartOne" type="SubType" minOccurs="0" maxOccurs="1"/>
                <xs:element name="PartTwo" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="SubType">
        <xs:sequence>
            <xs:element name="ElemOne" type="xs:string" />
        </xs:sequence>
    </xs:complexType>
</xs:schema>

和 XML:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<My_Data
    xmlns="http://www.mywebsite.com/schema/myschema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema">
    <PartOne>
        <ElemOne>thing</ElemOne>
    </PartOne>
    <PartTwo>123</PartTwo>
</My_Data>

我已经尝试了很多变体,包括添加 schemaLocation 属性,但它总是返回到目标命名空间。如果我从上面的例子中取出 ElemOne 并且不使用 targetNamespace,它解析没有问题。为什么我会得到这个错误?这实际上是命名空间的问题(在这种情况下,为什么在线工具无法捕捉到它?),还是其他问题?

编辑:这是我用来 运行 的 C++ 代码:

// g++ -g -Wall -pedantic -L /usr/lib -o schemasend schemasend.cc CustomParserErrorHandler.cc -lxerces-c

#include <xercesc/framework/MemBufInputSource.hpp>
#include "CustomParserErrorHandler.hh"
#include <string>
#include <iostream>

int main(int argc, char* argv[])
{
  xercesc::XMLPlatformUtils::Initialize();
  std::cout << "Intialized" << std::endl;
  try {
    // Parse document
    const std::string aXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?><My_Data xmlns=\"http://www.mywebsite.com/schema/myschema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema\"><PartOne><ElemOne>thing</ElemOne></PartOne><PartTwo>123</PartTwo></My_Data>";
    static std::string aXSDFilePath("MySchema.xsd");

    CustomParserErrorHandler aErrorHandler; // just a very basic implementation of error handling

    const xercesc::MemBufInputSource aInputSource(
      (const XMLByte*)aXML.c_str(), 
      static_cast<uint>(aXML.size()), 
      "stringBuffer");

    xercesc::XercesDOMParser* aParser = new xercesc::XercesDOMParser();
    aParser->cacheGrammarFromParse(true);

    aParser->setErrorHandler(&aErrorHandler);
    aParser->setDoNamespaces(true);
    aParser->setDoSchema(true);
    aParser->setValidationSchemaFullChecking(true);
    aParser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);
    aParser->setExternalNoNamespaceSchemaLocation((char*)NULL);
    aParser->setExternalNoNamespaceSchemaLocation(aXSDFilePath.c_str());

    aParser->setDoNamespaces(true);
    aParser->setDoSchema(true);
    aParser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);

    aParser->parse(aInputSource);
    xercesc::DOMDocument* aDocument = aParser->getDocument();
    if (!aErrorHandler.HasErrorOccurred())
    {
      std::cout << "--- PARSE WORKED ---" << std::endl;
      // do more things
    }
    else
    {
      std::cout <<"--- PARSE ERROR ---" << std::endl
        << aErrorHandler.GetErrorString().c_str() << std::endl
        << "--- IN XML ---" << std::endl
        << aXML.c_str() << std::endl;

        /* relevant error handler code:
          void CustomParserErrorHandler::HandleError(
              const xercesc::SAXParseException &aException,
              std::stringstream                &aStream)
          {
            aStream
              << xercesc::XMLString::transcode(aException.getMessage())
              << " at line " << aException.getLineNumber()
              << ", char " << aException.getColumnNumber()
              << " in file " 
              << xercesc::XMLString::transcode(aException.getSystemId())
              << std::endl;
          }
        */
    }
  }
  catch (const xercesc::XMLException& toCatch) {
    std::cout << "ERROR" << std::endl;
    return 1;
  }

  xercesc::XMLPlatformUtils::Terminate();
  std::cout << "bye" << std::endl;
  return 0;
}

问题出在我的 C++ 代码中,而不是 XML/XSD 文件中。当我注释掉行

aParser->setExternalNoNamespaceSchemaLocation(aXSDFilePath.c_str());

它不再给出错误信息。我不确定为什么这会产生影响,因为据我所知,命名空间中没有任何 not,但它解决了我看到的问题。