我有一个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;
}
答案 0 :(得分:0)
问题在于我的C ++代码而不是XML / XSD文件。当我注释掉这一行时
aParser->setExternalNoNamespaceSchemaLocation(aXSDFilePath.c_str());
它不再提供错误消息。我不确定为什么这会产生影响,因为据我所知,命名空间中没有 not ,但它解决了我所看到的问题。