【问题标题】:Error "different target namespace", but schema validates and namespaces match?错误“不同的目标命名空间”,但模式验证和命名空间匹配?
【发布时间】:2015-08-12 17:02:01
【问题描述】:

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

【问题讨论】:

    标签: xml xsd namespaces xsd-validation xerces


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2022-10-04
      • 1970-01-01
      • 2012-04-24
      • 2020-04-07
      • 1970-01-01
      • 2014-05-09
      • 2013-06-17
      • 1970-01-01
      • 2010-10-20
      相关资源
      最近更新 更多