没有命名空间的 xml 的 Java xsd 验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2991091/
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-29 23:50:46  来源:igfitidea点击:

Java xsd validation of xml without namespace

javaxmlvalidationxsd

提问by Alec Holmes

I want to validate an XML file against an XSD schema. The XML files root element does not have any namespace or xsi details. It has no attributes so just <root>.

我想根据 XSD 架构验证 XML 文件。XML 文件根元素没有任何命名空间或 xsi 详细信息。它没有属性所以只是<root>.

I have tried the following code from http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.htmlwith no luck as I receive cvc-elt.1: Cannot find the declaration of element 'root'

我已经尝试了http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html 中的以下代码,但我收到时没有运气 cvc-elt.1: Cannot find the declaration of element 'root'

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");

File schemaFile = new File("schema.xsd");

Schema xsdScheme = factory.newSchema(schemaFile);

Validator validator = xsdScheme.newValidator();

Source source = new StreamSource(xmlfile);

validator.validate(source);

The xml validates fine with the namespace headers included etc (added via xmlspy), but I would have thought the xml namespace could be declared without having to manually edit the source file?

使用包含的命名空间标头等(通过 xmlspy 添加),xml 可以很好地验证,但我原以为可以声明 xml 命名空间而无需手动编辑源文件?

Edit and Solution:

编辑和解决方案:

public static void validateAgainstXSD(File file) {

    try {
        SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");

        File schemaFile = new File("path/to/xsd");

        Schema xsdScheme = factory.newSchema(schemaFile);

        Validator validator = xsdScheme.newValidator();

        SAXSource source = new SAXSource(
                new NamespaceFilter(XMLReaderFactory.createXMLReader()),
                new InputSource(new FileInputStream(file)));

        validator.validate(source,null);

    } catch (Exception e) {
        e.printStackTrace();
    }

}

protected static class NamespaceFilter extends XMLFilterImpl {

    String requiredNamespace = "namespace";

    public NamespaceFilter(XMLReader parent) {
        super(parent);
    }

    @Override
    public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
        if(!arg0.equals(requiredNamespace)) 
            arg0 = requiredNamespace;
        super.startElement(arg0, arg1, arg2, arg3);
    }       
}

采纳答案by xcut

You have two separate concerns you need to take care of:

您需要处理两个不同的问题:

  1. Declaring the namespace that your document uses.
  2. Putting an xsi:schemaLocationattribute in the file to give a hint (!)where the schema is.
  1. 声明您的文档使用的命名空间。
  2. xsi:schemaLocation在文件中放置一个属性以给出模式所在的提示(!)

You can safely skip the second part, as the location is really only a hint. You cannot skip the first part. The namespace declared in the XML file is matched against the schema. Important, this:

您可以安全地跳过第二部分,因为位置实际上只是一个提示。您不能跳过第一部分。XML 文件中声明的命名空间与架构匹配。重要的是,这个:

<xml> ... </xml>

Is not the sameas this:

不一样的,因为这:

<xml xmlns="urn:foo"> ... </xml>

So you need to declare your namespace in the XML document, otherwise it will not correspond to your schema and you will get this error.

所以你需要在 XML 文档中声明你的命名空间,否则它将与你的架构不对应,你会得到这个错误。