macos 为什么这个通过 XSD 的 XML 验证在 libxml2 中失败(但在 xmllint 中成功),我该如何解决?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6284827/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 08:06:39  来源:igfitidea点击:

Why does this XML validation via XSD fail in libxml2 (but succeed in xmllint) and how do I fix it?

cxmlmacosxsdlibxml2

提问by mtree

If I run this XML validationvia xmllint:

如果我通过xmllint运行此XML 验证

xmllint --noout --schema schema.xsd test.xml

I get this successmessage:

我收到此成功消息:

.../test.xml validates

However if I run the same validationvia libxml2's C API:

但是,如果我通过libxml2 的 C API运行相同的验证

int result = xmlSchemaValidateDoc(...)

I get a return value of 1845and this failuremessage:

我得到一个返回值1845和这个失败消息:

Element '{http://example.com/XMLSchema/1.0}foo': No matching global declaration available for the validation root.

Which I can make absolutely no sense of. :(

我完全无法理解。:(



schema.xsd:

架构.xsd:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd" >
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://example.com/XMLSchema/1.0" targetNamespace="http://example.com/XMLSchema/1.0" elementFormDefault="qualified" attributeFormDefault="unqualified">

    <xs:element name="foo">
    </xs:element>
</xs:schema>


test.xml:

测试.xml:

<?xml version="1.0" encoding="UTF-8"?>

<foo xmlns="http://example.com/XMLSchema/1.0">
</foo>


main.c:

主文件:

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>

#include <libxml/parser.h>
#include <libxml/valid.h>
#include <libxml/xmlschemas.h>

u_int32_t get_file_size(const char *file_name) {
    struct stat buf;
    if ( stat(file_name, &buf) != 0 ) return(0);
    return (unsigned int)buf.st_size;
}

void handleValidationError(void *ctx, const char *format, ...) {
    char *errMsg;
    va_list args;
    va_start(args, format);
    vasprintf(&errMsg, format, args);
    va_end(args);
    fprintf(stderr, "Validation Error: %s", errMsg);
    free(errMsg);
}

int main (int argc, const char * argv[]) {
    const char *xsdPath = argv[1];
    const char *xmlPath = argv[2];

    printf("\n");

    printf("XSD File: %s\n", xsdPath);
    printf("XML File: %s\n", xmlPath);

    int xmlLength = get_file_size(xmlPath);
    char *xmlSource = (char *)malloc(sizeof(char) * xmlLength);

    FILE *p = fopen(xmlPath, "r");
    char c;
    unsigned int i = 0;
    while ((c = fgetc(p)) != EOF) {
        xmlSource[i++] = c;
    }
    printf("\n");

    printf("XML Source:\n\n%s\n", xmlSource);
    fclose(p);

    printf("\n");

    int result = 42;
    xmlSchemaParserCtxtPtr parserCtxt = NULL;
    xmlSchemaPtr schema = NULL;
    xmlSchemaValidCtxtPtr validCtxt = NULL;

    xmlDocPtr xmlDocumentPointer = xmlParseMemory(xmlSource, xmlLength);
    parserCtxt = xmlSchemaNewParserCtxt(xsdPath);

    if (parserCtxt == NULL) {
        fprintf(stderr, "Could not create XSD schema parsing context.\n");
        goto leave;
    }

    schema = xmlSchemaParse(parserCtxt);

    if (schema == NULL) {
        fprintf(stderr, "Could not parse XSD schema.\n");
        goto leave;
    }

    validCtxt = xmlSchemaNewValidCtxt(schema);

    if (!validCtxt) {
        fprintf(stderr, "Could not create XSD schema validation context.\n");
        goto leave;
    }

    xmlSetStructuredErrorFunc(NULL, NULL);
    xmlSetGenericErrorFunc(NULL, handleValidationError);
    xmlThrDefSetStructuredErrorFunc(NULL, NULL);
    xmlThrDefSetGenericErrorFunc(NULL, handleValidationError);

    result = xmlSchemaValidateDoc(validCtxt, xmlDocumentPointer);

leave:

    if (parserCtxt) {
        xmlSchemaFreeParserCtxt(parserCtxt);
    }

    if (schema) {
        xmlSchemaFree(schema);
    }

    if (validCtxt) {
        xmlSchemaFreeValidCtxt(validCtxt);
    }
    printf("\n");
    printf("Validation successful: %s (result: %d)\n", (result == 0) ? "YES" : "NO", result);

    return 0;
}


console output:

控制台输出:

XSD File: /Users/dephiniteloop/Desktop/xml_validate/schema.xsd
XML File: /Users/dephiniteloop/Desktop/xml_validate/test.gkml

XML Source:

<?xml version="1.0" encoding="UTF-8"?>

<foo xmlns="http://example.com/XMLSchema/1.0">
</foo>

Validation Error: Element '{http://example.com/XMLSchema/1.0}foo': No matching global declaration available for the validation root.

Validation successful: NO (result: 1845)


In case it matters: I'm on OSX 10.6.7with its default libxml2.dylib
(/Developer/SDKs/MacOSX10.6.sdk/usr/lib/libxml2.2.7.3.dylib)

如果重要:我在OSX 10.6.7 上使用它的默认libxml2.dylib
(/Developer/SDKs/MacOSX10.6.sdk/usr/lib/libxml2.2.7.3.dylib)

采纳答案by mtree

After getting some help on the gnome project's xml mailing-listit appears as if my error is not caused by a bug of mine, but rather by a bug of OSX 10.6.x's distribution (v2.7.3) of libxml2.
(as in: same code works for others, yet fails for me OSX' legacy distribution)

gnome 项目的 xml 邮件列表上获得一些帮助后,似乎我的错误不是由我的错误引起的而是由 OSX 10.6.x 的 libxml2 发行版 (v2.7.3) 的错误引起的
(如:相同的代码对其他人有效,但对我来说却失败了 OSX 的遗留发行版)

I checked the libxml2 release notes and found two candidates:

我查看了 libxml2 发行说明,发现了两个候选对象:

Release notes of Update 2.7.4 list the following bug fix:

更新 2.7.4 的发行说明列出了以下错误修复:

  • "579746 XSD validation not correct / nilable groups (Daniel Veillard)"
  • “579746 XSD 验证不正确/无效组(Daniel Veillard)”

Release notes of Update 2.7.8 list the following bug fix:

更新 2.7.8 的发行说明列出了以下错误修复:

  • "Fix errors in XSD double validation check (Csaba Raduly)"
  • “修复 XSD 双重验证检查 (Csaba Raduly) 中的错误”

Haven't yet had success getting the latest build (v2.7.8) of libxml2 to work with my project (or rather Xcode in general) though.

不过,还没有成功地将 libxml2 的最新版本 (v2.7.8) 与我的项目(或者更确切地说是一般的 Xcode)一起使用。

回答by jsa

I tried your content and code on Ubuntu Linux. Worked without any objection.

我在 Ubuntu Linux 上尝试了您的内容和代码。没有任何异议地工作。

Build command:

构建命令:

gcc -Wall -I/usr/include/libxml2 main.c -lxml2 -o xmlvalid 

Run command:

运行命令:

./xmlvalid ./schema.xsd ./test.xml

Output:

输出:

XSD File: ./schema.xsd
XML File: ./test.xml

XML Source:

XML 来源:

<?xml version="1.0" encoding="UTF-8"?>

<foo xmlns="http://example.com/XMLSchema/1.0">
</foo>

Validation successful: YES (result: 0)

验证成功:是(结果:0)

回答by John Cowan

Your schema puts the element foo into the targetNamespace (that's what elementdefault="qualified" means), but your instance document doesn't declare that namespace or any other. So the foos don't actually match.

您的架构将元素 foo 放入 targetNamespace(这就是 elementdefault="qualified" 的意思),但您的实例文档没有声明该名称空间或任何其他名称。所以 foos 实际上并不匹配。