我在libxml2中遇到验证问题,因为xmlSchemaValidateDoc失败并出现以下错误:
Element '{http://evcom.dk}cdr', attribute 'xmlns:xs': The attribute
'xmlns:xs' is not allowed.
Element '{http://evcom.dk}cdr', attribute 'xmlns:tns': The attribute
'xmlns:tns' is not allowed.
生成的xml文件在使用xmllint时进行验证,经过一些处理后我发现该文件还验证了我是否在进行验证之前保存并回读了xml文档。
换句话说,使用(简化 - 无错误检查)代码:
char *path = "/home/dev/cdr.xml";
char *namespace = "http://evcom.dk";
xmlDocPtr pDoc = xmlNewDoc(BAD_CAST "1.0");
xmlNsPtr tns = xmlNewNs(NULL, BAD_CAST namespace, BAD_CAST "tns");
xmlNodePtr xnpRoot = xmlNewNode(tns, BAD_CAST "cdr");
xmlNewProp(xnpRoot, BAD_CAST "xmlns:xs",
BAD_CAST "http://www.w3.org/2001/XMLSchema");
xmlNewProp(xnpRoot, BAD_CAST "xmlns:tns", BAD_CAST namespace);
xmlDocSetRootElement(pDoc, xnpRoot);
xmlNodePtr xnpChild1 = xmlNewChild(xnpRoot, tns, BAD_CAST "test", NULL);
xmlAddChild(xnpChild1, xmlNewText(BAD_CAST "TEST"));
xmlSaveFormatFileEnc(path, pDoc, "UTF-8", 1);
//xmlFreeDoc(pDoc);
//pDoc = xmlReadFile(path, NULL, XML_PARSE_NONET);
char *schemaPath = "/home/dev/cdr.xsd";
xmlDocPtr pSchemaDoc = xmlReadFile(schemaPath, NULL, XML_PARSE_NONET);
xmlSchemaParserCtxtPtr pParser = xmlSchemaNewDocParserCtxt(pSchemaDoc);
xmlSchemaPtr pSchema = xmlSchemaParse(pParser);
xmlSchemaValidCtxtPtr pSchemaCtxt = xmlSchemaNewValidCtxt(pSchema);
xmlSchemaSetValidErrors(pSchemaCtxt, NULL, NULL, NULL);
xmlSchemaValidateDoc(pSchemaCtxt, pDoc);
doc没有验证,但是如果我在“char * schemaPath”行之前取消注释两行,则doc会验证。
已发现此问题存在于x86和arm linux 32位平台上,使用libxml版本2.9.1和2.9.2,使用预编译或我自己编译的库版本。
请问有人能说清楚吗?
供参考,xsd文件:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://evcom.dk"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://evcom.dk">
<xs:element name="cdr">
<xs:complexType>
<xs:sequence>
<xs:element name="test">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="9"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
生成的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<tns:cdr xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://evcom.dk">
<tns:test>TEST</tns:test>
</tns:cdr>
答案 0 :(得分:0)
永远不要添加xmlNewProp
的命名空间。此功能仅应用于属性。使用xmlNewNs
添加名称空间声明。替换行
xmlNewProp(xnpRoot, BAD_CAST "xmlns:xs",
BAD_CAST "http://www.w3.org/2001/XMLSchema");
xmlNewProp(xnpRoot, BAD_CAST "xmlns:tns", BAD_CAST namespace);
与
xmlNewNs(xnpRoot, BAD_CAST "http://www.w3.org/2001/XMLSchema",
BAD_CAST "xs");
(隐式添加xmlns:tns
声明。)