针对XSD架构的Java XML验证

时间:2023-01-14 08:16:54
private void validateXML(DOMSource source) throws Exception {
    URL schemaFile = new URL("http://www.csc.liv.ac.uk/~valli/modules.xsd");
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
    Schema schema = schemaFactory.newSchema(schemaFile);

    Validator validator = schema.newValidator();
    DOMResult result = new DOMResult();
    try {
        validator.validate(source, result); 
        System.out.println("is valid");
    } catch (SAXException e) {
        System.out.println("not valid because " + e.getLocalizedMessage());
    }
}

But this returns an error saying: Exception in thread "main" java.lang.IllegalArgumentException: No SchemaFactory that implements the schema language specified by: http://www.w3.org/2001/XMLSchema -instance could be loaded

但是这会返回一个错误:线程“main”中的异常java.lang.IllegalArgumentException:没有实现以下指定的模式语言的SchemaFactory:http://www.w3.org/2001/XMLSchema -instance可以加载

Is this a problem with my code or with the actual xsd file?

这是我的代码或实际的xsd文件的问题?

2 个解决方案

#1


16  

That error means that your installed Java doesn't have any classes that can parse XMLSchema files, so it's not a problem with the schema or your code.

该错误意味着您安装的Java没有任何可以解析XMLSchema文件的类,因此它不是架构或代码的问题。

I'm pretty sure recent JREs have the appropriate classes by default, so can you get us the output of java -version?

我很确定最近的JRE默认有相应的类,所以你能得到java -version的输出吗?


Update:

更新:

You're using the wrong XMLContants string. You want: XMLConstants.W3C_XML_SCHEMA_NS_URI

您正在使用错误的XMLContants字符串。你想要:XMLConstants.W3C_XML_SCHEMA_NS_URI

#2


2  

Those files are based on the underlying system. I had the same issue when I was programming a project for Android. I found that I had to use Xerces-for-Android to solve my problem.

这些文件基于底层系统。我在编写Android项目时遇到了同样的问题。我发现我必须使用Xerces-for-Android来解决我的问题。

The following worked for me for validation on Android, if your code relates to Android perhaps it will help, if it doesn't then perhaps the approach will help you with your underlying system:

以下是我在Android上验证的问题,如果你的代码与Android有关,也许它会有所帮助,如果它没有,那么这个方法可能会帮助你使用底层系统:

  1. Create a validation utility.
  2. 创建验证实用程序。
  3. Get both the xml and xsd into file on the android OS and use the validation utility against it.
  4. 将android和OS上的xml和xsd都放到文件中,并使用验证实用程序。
  5. Use Xerces-For-Android to do the validation.
  6. 使用Xerces-For-Android进行验证。

Android does support some packages which we can use, I created my xml validation utility based on: http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html

Android确实支持我们可以使用的一些软件包,我根据以下内容创建了我的xml验证实用程序:http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html

My initial sandbox testing was pretty smooth with java, then I tried to port it over to Dalvik and found that my code did not work. Some things just aren't supported the same with Dalvik, so I made some modifications.

我最初的沙箱测试非常流畅,然后我尝试将其移植到Dalvik并发现我的代码不起作用。有些事情与Dalvik不相同,所以我做了一些修改。

I found a reference to xerces for android, so I modified my sandbox test of (the following doesn't work with android, the example after this does):

我找到了一个对xerces for android的引用,所以我修改了我的沙盒测试(以下不适用于android,这之后的例子):

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.w3c.dom.Document;

/**
 * A Utility to help with xml communication validation.
 */
public class XmlUtil {

    /**
     * Validation method. 
     * Base code/example from: http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html
     * 
     * @param xmlFilePath The xml file we are trying to validate.
     * @param xmlSchemaFilePath The schema file we are using for the validation. This method assumes the schema file is valid.
     * @return True if valid, false if not valid or bad parse. 
     */
    public static boolean validate(String xmlFilePath, String xmlSchemaFilePath) {

        // parse an XML document into a DOM tree
        DocumentBuilder parser = null;
        Document document;

        // Try the validation, we assume that if there are any issues with the validation
        // process that the input is invalid.
        try {
            // validate the DOM tree
            parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            document = parser.parse(new File(xmlFilePath));

            // create a SchemaFactory capable of understanding WXS schemas
            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

            // load a WXS schema, represented by a Schema instance
            Source schemaFile = new StreamSource(new File(xmlSchemaFilePath));
            Schema schema = factory.newSchema(schemaFile);

            // create a Validator instance, which can be used to validate an instance document
            Validator validator = schema.newValidator();
            validator.validate(new DOMSource(document));
        } catch (Exception e) {
            // Catches: SAXException, ParserConfigurationException, and IOException.
            return false;
        }     

        return true;
    }
}

The above code had to be modified some to work with xerces for android (http://gc.codehum.com/p/xerces-for-android/). You need SVN to get the project, the following are some crib notes:

上面的代码必须修改一些与xerces for android(http://gc.codehum.com/p/xerces-for-android/)一起使用。您需要SVN才能获得该项目,以下是一些小册子:

download xerces-for-android
    download silk svn (for windows users) from http://www.sliksvn.com/en/download
        install silk svn (I did complete install)
        Once the install is complete, you should have svn in your system path.
        Test by typing "svn" from the command line.
        I went to my desktop then downloaded the xerces project by:
            svn checkout http://xerces-for-android.googlecode.com/svn/trunk/ xerces-for-android-read-only
        You should then have a new folder on your desktop called xerces-for-android-read-only

With the above jar (Eventually I'll make it into a jar, just copied it directly into my source for quick testing. If you wish to do the same, you can making the jar quickly with Ant (http://ant.apache.org/manual/using.html)), I was able to get the following to work for my xml validation:

使用上面的jar(最终我将它变成一个jar,只需将它直接复制到我的源代码中进行快速测试。如果你想做同样的事情,你可以使用Ant快速制作jar(http://ant.apache .org / manual / using.html)),我能够获得以下工作来进行我的xml验证:

import java.io.File;
import java.io.IOException;

import mf.javax.xml.transform.Source;
import mf.javax.xml.transform.stream.StreamSource;
import mf.javax.xml.validation.Schema;
import mf.javax.xml.validation.SchemaFactory;
import mf.javax.xml.validation.Validator;
import mf.org.apache.xerces.jaxp.validation.XMLSchemaFactory;

import org.xml.sax.SAXException;

/**
 * A Utility to help with xml communication validation.
 */public class XmlUtil {

    /**
     * Validation method. 
     * 
     * @param xmlFilePath The xml file we are trying to validate.
     * @param xmlSchemaFilePath The schema file we are using for the validation. This method assumes the schema file is valid.
     * @return True if valid, false if not valid or bad parse or exception/error during parse. 
     */
    public static boolean validate(String xmlFilePath, String xmlSchemaFilePath) {

        // Try the validation, we assume that if there are any issues with the validation
        // process that the input is invalid.
        try {
            SchemaFactory  factory = new XMLSchemaFactory();
            Source schemaFile = new StreamSource(new File(xmlSchemaFilePath));
            Source xmlSource = new StreamSource(new File(xmlFilePath));
            Schema schema = factory.newSchema(schemaFile);
            Validator validator = schema.newValidator();
            validator.validate(xmlSource);
        } catch (SAXException e) {
            return false;
        } catch (IOException e) {
            return false;
        } catch (Exception e) {
            // Catches everything beyond: SAXException, and IOException.
            e.printStackTrace();
            return false;
        } catch (Error e) {
            // Needed this for debugging when I was having issues with my 1st set of code.
            e.printStackTrace();
            return false;
        }

        return true;
    }
}

Some Side Notes:

一些附注:

For creating the files, I made a simple file utility to write string to files:

为了创建文件,我创建了一个简单的文件实用程序来将字符串写入文件:

public static void createFileFromString(String fileText, String fileName) {
    try {
        File file = new File(fileName);
        BufferedWriter output = new BufferedWriter(new FileWriter(file));
        output.write(fileText);
        output.close();
    } catch ( IOException e ) {
       e.printStackTrace();
    }
}

I also needed to write to an area that I had access to, so I made use of:

我还需要写一个我可以访问的区域,所以我使用了:

String path = this.getActivity().getPackageManager().getPackageInfo(getPackageName(), 0).applicationInfo.dataDir;   

A little hackish, it works. I'm sure there is a more succinct way of doing this, however I figured I'd share my success, as there weren't any good examples that I found.

有点hackish,它的工作原理。我确信有更简洁的方法可以做到这一点,但我想我会分享我的成功,因为我没有找到任何好的例子。

#1


16  

That error means that your installed Java doesn't have any classes that can parse XMLSchema files, so it's not a problem with the schema or your code.

该错误意味着您安装的Java没有任何可以解析XMLSchema文件的类,因此它不是架构或代码的问题。

I'm pretty sure recent JREs have the appropriate classes by default, so can you get us the output of java -version?

我很确定最近的JRE默认有相应的类,所以你能得到java -version的输出吗?


Update:

更新:

You're using the wrong XMLContants string. You want: XMLConstants.W3C_XML_SCHEMA_NS_URI

您正在使用错误的XMLContants字符串。你想要:XMLConstants.W3C_XML_SCHEMA_NS_URI

#2


2  

Those files are based on the underlying system. I had the same issue when I was programming a project for Android. I found that I had to use Xerces-for-Android to solve my problem.

这些文件基于底层系统。我在编写Android项目时遇到了同样的问题。我发现我必须使用Xerces-for-Android来解决我的问题。

The following worked for me for validation on Android, if your code relates to Android perhaps it will help, if it doesn't then perhaps the approach will help you with your underlying system:

以下是我在Android上验证的问题,如果你的代码与Android有关,也许它会有所帮助,如果它没有,那么这个方法可能会帮助你使用底层系统:

  1. Create a validation utility.
  2. 创建验证实用程序。
  3. Get both the xml and xsd into file on the android OS and use the validation utility against it.
  4. 将android和OS上的xml和xsd都放到文件中,并使用验证实用程序。
  5. Use Xerces-For-Android to do the validation.
  6. 使用Xerces-For-Android进行验证。

Android does support some packages which we can use, I created my xml validation utility based on: http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html

Android确实支持我们可以使用的一些软件包,我根据以下内容创建了我的xml验证实用程序:http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html

My initial sandbox testing was pretty smooth with java, then I tried to port it over to Dalvik and found that my code did not work. Some things just aren't supported the same with Dalvik, so I made some modifications.

我最初的沙箱测试非常流畅,然后我尝试将其移植到Dalvik并发现我的代码不起作用。有些事情与Dalvik不相同,所以我做了一些修改。

I found a reference to xerces for android, so I modified my sandbox test of (the following doesn't work with android, the example after this does):

我找到了一个对xerces for android的引用,所以我修改了我的沙盒测试(以下不适用于android,这之后的例子):

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.w3c.dom.Document;

/**
 * A Utility to help with xml communication validation.
 */
public class XmlUtil {

    /**
     * Validation method. 
     * Base code/example from: http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html
     * 
     * @param xmlFilePath The xml file we are trying to validate.
     * @param xmlSchemaFilePath The schema file we are using for the validation. This method assumes the schema file is valid.
     * @return True if valid, false if not valid or bad parse. 
     */
    public static boolean validate(String xmlFilePath, String xmlSchemaFilePath) {

        // parse an XML document into a DOM tree
        DocumentBuilder parser = null;
        Document document;

        // Try the validation, we assume that if there are any issues with the validation
        // process that the input is invalid.
        try {
            // validate the DOM tree
            parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            document = parser.parse(new File(xmlFilePath));

            // create a SchemaFactory capable of understanding WXS schemas
            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

            // load a WXS schema, represented by a Schema instance
            Source schemaFile = new StreamSource(new File(xmlSchemaFilePath));
            Schema schema = factory.newSchema(schemaFile);

            // create a Validator instance, which can be used to validate an instance document
            Validator validator = schema.newValidator();
            validator.validate(new DOMSource(document));
        } catch (Exception e) {
            // Catches: SAXException, ParserConfigurationException, and IOException.
            return false;
        }     

        return true;
    }
}

The above code had to be modified some to work with xerces for android (http://gc.codehum.com/p/xerces-for-android/). You need SVN to get the project, the following are some crib notes:

上面的代码必须修改一些与xerces for android(http://gc.codehum.com/p/xerces-for-android/)一起使用。您需要SVN才能获得该项目,以下是一些小册子:

download xerces-for-android
    download silk svn (for windows users) from http://www.sliksvn.com/en/download
        install silk svn (I did complete install)
        Once the install is complete, you should have svn in your system path.
        Test by typing "svn" from the command line.
        I went to my desktop then downloaded the xerces project by:
            svn checkout http://xerces-for-android.googlecode.com/svn/trunk/ xerces-for-android-read-only
        You should then have a new folder on your desktop called xerces-for-android-read-only

With the above jar (Eventually I'll make it into a jar, just copied it directly into my source for quick testing. If you wish to do the same, you can making the jar quickly with Ant (http://ant.apache.org/manual/using.html)), I was able to get the following to work for my xml validation:

使用上面的jar(最终我将它变成一个jar,只需将它直接复制到我的源代码中进行快速测试。如果你想做同样的事情,你可以使用Ant快速制作jar(http://ant.apache .org / manual / using.html)),我能够获得以下工作来进行我的xml验证:

import java.io.File;
import java.io.IOException;

import mf.javax.xml.transform.Source;
import mf.javax.xml.transform.stream.StreamSource;
import mf.javax.xml.validation.Schema;
import mf.javax.xml.validation.SchemaFactory;
import mf.javax.xml.validation.Validator;
import mf.org.apache.xerces.jaxp.validation.XMLSchemaFactory;

import org.xml.sax.SAXException;

/**
 * A Utility to help with xml communication validation.
 */public class XmlUtil {

    /**
     * Validation method. 
     * 
     * @param xmlFilePath The xml file we are trying to validate.
     * @param xmlSchemaFilePath The schema file we are using for the validation. This method assumes the schema file is valid.
     * @return True if valid, false if not valid or bad parse or exception/error during parse. 
     */
    public static boolean validate(String xmlFilePath, String xmlSchemaFilePath) {

        // Try the validation, we assume that if there are any issues with the validation
        // process that the input is invalid.
        try {
            SchemaFactory  factory = new XMLSchemaFactory();
            Source schemaFile = new StreamSource(new File(xmlSchemaFilePath));
            Source xmlSource = new StreamSource(new File(xmlFilePath));
            Schema schema = factory.newSchema(schemaFile);
            Validator validator = schema.newValidator();
            validator.validate(xmlSource);
        } catch (SAXException e) {
            return false;
        } catch (IOException e) {
            return false;
        } catch (Exception e) {
            // Catches everything beyond: SAXException, and IOException.
            e.printStackTrace();
            return false;
        } catch (Error e) {
            // Needed this for debugging when I was having issues with my 1st set of code.
            e.printStackTrace();
            return false;
        }

        return true;
    }
}

Some Side Notes:

一些附注:

For creating the files, I made a simple file utility to write string to files:

为了创建文件,我创建了一个简单的文件实用程序来将字符串写入文件:

public static void createFileFromString(String fileText, String fileName) {
    try {
        File file = new File(fileName);
        BufferedWriter output = new BufferedWriter(new FileWriter(file));
        output.write(fileText);
        output.close();
    } catch ( IOException e ) {
       e.printStackTrace();
    }
}

I also needed to write to an area that I had access to, so I made use of:

我还需要写一个我可以访问的区域,所以我使用了:

String path = this.getActivity().getPackageManager().getPackageInfo(getPackageName(), 0).applicationInfo.dataDir;   

A little hackish, it works. I'm sure there is a more succinct way of doing this, however I figured I'd share my success, as there weren't any good examples that I found.

有点hackish,它的工作原理。我确信有更简洁的方法可以做到这一点,但我想我会分享我的成功,因为我没有找到任何好的例子。