错误"不同的目标命名空间",但架构验证和命名空间匹配?

时间:2015-08-12 17:02:02

标签: xml xsd namespaces xsd-validation xerces

我有一个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;
}

1 个答案:

答案 0 :(得分:0)

问题在于我的C ++代码而不是XML / XSD文件。当我注释掉这一行时

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

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