根据XSD文件验证XML文件的最佳方法是什么?

时间:2022-09-15 20:31:11

I'm generating some xml files that needs to conform to an xsd file that was given to me. What's the best way to verify they conform?

我正在生成一些xml文件,这些文件需要符合给我的xsd文件。验证它们是否符合的最佳方法是什么?

12 个解决方案

#1


294  

The Java runtime library supports validation. Last time I checked this was the Apache Xerces parser under the covers. You should probably use a javax.xml.validation.Validator.

Java运行时库支持验证。上次检查时,我看到的是隐藏在幕后的Apache Xerces解析器。您可能应该使用javax.xml. valid.validator。

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import java.net.URL;
import org.xml.sax.SAXException;
//import java.io.File; // if you use File
import java.io.IOException;
...
URL schemaFile = new URL("http://host:port/filename.xsd");
// webapp example xsd: 
// URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd");
// local file example:
// File schemaFile = new File("/location/to/localfile.xsd"); // etc.
Source xmlFile = new StreamSource(new File("web.xml"));
SchemaFactory schemaFactory = SchemaFactory
    .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
  Schema schema = schemaFactory.newSchema(schemaFile);
  Validator validator = schema.newValidator();
  validator.validate(xmlFile);
  System.out.println(xmlFile.getSystemId() + " is valid");
} catch (SAXException e) {
  System.out.println(xmlFile.getSystemId() + " is NOT valid reason:" + e);
} catch (IOException e) {}

The schema factory constant is the string http://www.w3.org/2001/XMLSchema which defines XSDs. The above code validates a WAR deployment descriptor against the URL http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd but you could just as easily validate against a local file.

模式工厂常量是字符串http://www.w3.org/2001/XMLSchema,定义了XSDs。上面的代码针对URL http://java.sun.com/xml/ns/j2ee/webapp_2_4 .xsd验证WAR部署描述符,但是您也可以轻松地对本地文件进行验证。

You should not use the DOMParser to validate a document (unless your goal is to create a document object model anyway). This will start creating DOM objects as it parses the document - wasteful if you aren't going to use them.

您不应该使用DOMParser来验证文档(除非您的目标是创建文档对象模型)。这将在解析文档时开始创建DOM对象——如果您不打算使用它们,则会造成浪费。

#2


23  

Here's how to do it using Xerces2. A tutorial for this, here (req. signup).

以下是如何使用Xerces2进行此操作。这里有本教程(req)。注册)。

Original attribution: blatantly copied from here:

原创署名:公然抄袭:

import org.apache.xerces.parsers.DOMParser;
import java.io.File;
import org.w3c.dom.Document;

public class SchemaTest {
  public static void main (String args[]) {
      File docFile = new File("memory.xml");
      try {
        DOMParser parser = new DOMParser();
        parser.setFeature("http://xml.org/sax/features/validation", true);
        parser.setProperty(
             "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", 
             "memory.xsd");
        ErrorChecker errors = new ErrorChecker();
        parser.setErrorHandler(errors);
        parser.parse("memory.xml");
     } catch (Exception e) {
        System.out.print("Problem parsing the file.");
     }
  }
}

#3


19  

We build our project using ant, so we can use the schemavalidate task to check our config files:

我们使用ant构建项目,因此可以使用schemavalidate任务检查配置文件:

<schemavalidate> 
    <fileset dir="${configdir}" includes="**/*.xml" />
</schemavalidate>

Now naughty config files will fail our build!

现在淘气的配置文件将会使我们的构建失败!

http://ant.apache.org/manual/Tasks/schemavalidate.html

http://ant.apache.org/manual/Tasks/schemavalidate.html

#4


10  

I found this site to be helpful, too.

我发现这个网站也很有帮助。

http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html

http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html

It's the one that actually worked for me with a minimum of fuss.

这是对我最有效的方法。

#5


7  

Since this is a popular question, I would also like to point out that java can validate against a "referred to" xsd, for instance if the .xml file itself specifies an XSD, using xsi:SchemaLocation or xsi:noNamespaceSchemaLocation (or xsi for particular namespaces) as stated here:

由于这是一个流行的问题,我还想指出,java可以使用xsi:SchemaLocation或xsi:noNamespaceSchemaLocation(或xsi:特定名称空间)来验证“引用”xsd,例如.xml文件本身指定了xsd:

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd">
  ...

or SchemaLocation (always a list of namespace to xsd mappings)

或者SchemaLocation(始终是xsd映射的命名空间列表)

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:SchemaLocation="http://www.example.com/document http://www.example.com/document.xsd">
  ...

"If you create a schema without specifying a URL, file, or source, then the Java language creates one that looks in the document being validated to find the schema it should use. For example:"

如果您创建了一个模式而没有指定URL、文件或源,那么Java语言将创建一个模式,该模式将在被验证的文档中查找它应该使用的模式。例如:“

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

and this works for multiple namespaces, etc. The problem with this approach is that the xmlsns:xsi is probably a network location, so it'll go out and hit the network with each and every validation, not always optimal.

这种方法的问题是,xmlsns:xsi可能是一个网络位置,所以每次验证时它都会出去攻击网络,并不总是最优的。

Here's an example that validates an XML file against any XSD's it references (even if it has to pull them from the network):

下面的示例针对XSD的it引用验证XML文件(即使它必须从网络中提取它们):

  public static void verifyValidatesInternalXsd(String filename) throws Exception {
    InputStream xmlStream = new new FileInputStream(filename);
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);
    factory.setNamespaceAware(true);
    factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                 "http://www.w3.org/2001/XMLSchema");
    DocumentBuilder builder = factory.newDocumentBuilder();
    builder.setErrorHandler(new RaiseOnErrorHandler());
    builder.parse(new InputSource(xmlStream));
    xmlStream.close();
  }

  public static class RaiseOnErrorHandler implements ErrorHandler {
    public void warning(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void error(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void fatalError(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
  }

You can avoid pulling referenced XSD's from the network, even though the xml files reference url's, by specifying the xsd manually (see some other answers here) or by using an "XML catalog" style resolver. Spring apparently also can intercept the URL requests to serve local files for validations. Or you can set your own via setResourceResolver, ex:

您可以通过手动指定XSD(请参阅此处的一些其他答案)或使用“xml编目”样式解析器,避免从网络中提取引用的XSD,即使xml文件引用url是引用的。Spring显然也可以拦截URL请求,以提供本地文件的验证。或者你也可以通过setResourceResolver,例如:

Source xmlFile = new StreamSource(xmlFileLocation);
SchemaFactory schemaFactory = SchemaFactory
                                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setResourceResolver(new LSResourceResolver() {
  @Override
  public LSInput resolveResource(String type, String namespaceURI,
                                 String publicId, String systemId, String baseURI) {
    InputSource is = new InputSource(
                           getClass().getResourceAsStream(
                          "some_local_file_in_the_jar.xsd"));
                          // or lookup by URI, etc...
    return new Input(is); // for class Input see 
                          // https://*.com/a/2342859/32453
  }
});
validator.validate(xmlFile);

See also here for another tutorial.

请参见这里的另一个教程。

#6


4  

Using Java 7 you can follow the documentation provided in package description.

使用Java 7,您可以遵循包描述中提供的文档。

// parse an XML document into a DOM tree
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = parser.parse(new File("instance.xml"));

// 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("mySchema.xsd"));
Schema schema = factory.newSchema(schemaFile);

// create a Validator instance, which can be used to validate an instance document
Validator validator = schema.newValidator();

// validate the DOM tree
try {
    validator.validate(new DOMSource(document));
} catch (SAXException e) {
    // instance document is invalid!
}

#7


3  

One more answer: since you said you need to validate files you are generating (writing), you might want to validate content while you are writing, instead of first writing, then reading back for validation. You can probably do that with JDK API for Xml validation, if you use SAX-based writer: if so, just link in validator by calling 'Validator.validate(source, result)', where source comes from your writer, and result is where output needs to go.

还有一个答案:既然您说过您需要验证正在生成(写入)的文件,那么您可能希望在编写时验证内容,而不是先编写,然后再读取以进行验证。如果您使用基于sax的writer:如果可以,只需通过调用“validator”在validator中链接验证器。验证(源,结果)',源来自您的作者,结果是输出需要去的地方。

Alternatively if you use Stax for writing content (or a library that uses or can use stax), Woodstox can also directly support validation when using XMLStreamWriter. Here's a blog entry showing how that is done:

另外,如果您使用Stax来编写内容(或者使用或可以使用Stax的库),那么在使用XMLStreamWriter时,Woodstox也可以直接支持验证。这里有一个博客条目展示了这是如何做到的:

#8


2  

If you are generating XML files programatically, you may want to look at the XMLBeans library. Using a command line tool, XMLBeans will automatically generate and package up a set of Java objects based on an XSD. You can then use these objects to build an XML document based on this schema.

如果您正在程序化地生成XML文件,您可能需要查看XMLBeans库。使用命令行工具,XMLBeans将根据XSD自动生成并打包一组Java对象。然后,您可以使用这些对象来基于这个模式构建XML文档。

It has built-in support for schema validation, and can convert Java objects to an XML document and vice-versa.

它内置了对模式验证的支持,可以将Java对象转换为XML文档,反之亦然。

Castor and JAXB are other Java libraries that serve a similar purpose to XMLBeans.

Castor和JAXB是其他Java库,它们的用途与XMLBeans相似。

#9


2  

If you have a Linux-Machine you could use the free command-line tool SAXCount. I found this very usefull.

如果你有一台linux机器,你可以使用免费的命令行工具SAXCount。我发现这很有用。

SAXCount -f -s -n my.xml

It validates against dtd and xsd. 5s for a 50MB file.

它对dtd和xsd进行验证。5s用于50MB文件。

In debian squeeze it is located in the package "libxerces-c-samples".

在debian挤密中,它位于“libxerces-c-sample”包中。

The definition of the dtd and xsd has to be in the xml! You can't config them separately.

dtd和xsd的定义必须在xml中!不能单独配置它们。

#10


0  

Are you looking for a tool or a library?

你在找工具还是图书馆?

As far as libraries goes, pretty much the de-facto standard is Xerces2 which has both C++ and Java versions.

就库而言,实际上的标准是Xerces2,它有c++和Java版本。

Be fore warned though, it is a heavy weight solution. But then again, validating XML against XSD files is a rather heavy weight problem.

不过要注意的是,这是一个沉重的负担。但同样,根据XSD文件验证XML是一个相当重的问题。

As for a tool to do this for you, XMLFox seems to be a decent freeware solution, but not having used it personally I can't say for sure.

至于为您实现这一点的工具,XMLFox似乎是一个不错的免费软件解决方案,但我不能肯定地说,它并没有亲自使用它。

#11


0  

With JAXB, you could use the code below:

使用JAXB,您可以使用以下代码:

    @Test
public void testCheckXmlIsValidAgainstSchema() {
    logger.info("Validating an XML file against the latest schema...");

    MyValidationEventCollector vec = new MyValidationEventCollector();

    validateXmlAgainstSchema(vec, inputXmlFileName, inputXmlSchemaName, inputXmlRootClass);

    assertThat(vec.getValidationErrors().isEmpty(), is(expectedValidationResult));
}

private void validateXmlAgainstSchema(final MyValidationEventCollector vec, final String xmlFileName, final String xsdSchemaName, final Class<?> rootClass) {
    try (InputStream xmlFileIs = Thread.currentThread().getContextClassLoader().getResourceAsStream(xmlFileName);) {
        final JAXBContext jContext = JAXBContext.newInstance(rootClass);
        // Unmarshal the data from InputStream
        final Unmarshaller unmarshaller = jContext.createUnmarshaller();

        final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        final InputStream schemaAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xsdSchemaName);
        unmarshaller.setSchema(sf.newSchema(new StreamSource(schemaAsStream)));

        unmarshaller.setEventHandler(vec);

        unmarshaller.unmarshal(new StreamSource(xmlFileIs), rootClass).getValue(); // The Document class is the root object in the XML file you want to validate

        for (String validationError : vec.getValidationErrors()) {
            logger.trace(validationError);
        }
    } catch (final Exception e) {
        logger.error("The validation of the XML file " + xmlFileName + " failed: ", e);
    }
}

class MyValidationEventCollector implements ValidationEventHandler {
    private final List<String> validationErrors;

    public MyValidationEventCollector() {
        validationErrors = new ArrayList<>();
    }

    public List<String> getValidationErrors() {
        return Collections.unmodifiableList(validationErrors);
    }

    @Override
    public boolean handleEvent(final ValidationEvent event) {
        String pattern = "line {0}, column {1}, error message {2}";
        String errorMessage = MessageFormat.format(pattern, event.getLocator().getLineNumber(), event.getLocator().getColumnNumber(),
                event.getMessage());
        if (event.getSeverity() == ValidationEvent.FATAL_ERROR) {
            validationErrors.add(errorMessage);
        }
        return true; // you collect the validation errors in a List and handle them later
    }
}

#12


-2  

I had to validate an XML against XSD just one time, so I tried XMLFox. I found it to be very confusing and weird. The help instructions didn't seem to match the interface.

我只需要对XSD验证一次XML,所以我尝试了XMLFox。我发现它非常令人困惑和奇怪。帮助指令似乎与接口不匹配。

I ended up using LiquidXML Studio 2008 (v6) which was much easier to use and more immediately familiar (the UI is very similar to Visual Basic 2008 Express, which I use frequently). The drawback: the validation capability is not in the free version, so I had to use the 30 day trial.

最后,我使用了LiquidXML Studio 2008 (v6),它更容易使用,也更熟悉(UI与我经常使用的Visual Basic 2008 Express非常相似)。缺点:验证功能不在免费版本中,所以我不得不使用30天的测试。

#1


294  

The Java runtime library supports validation. Last time I checked this was the Apache Xerces parser under the covers. You should probably use a javax.xml.validation.Validator.

Java运行时库支持验证。上次检查时,我看到的是隐藏在幕后的Apache Xerces解析器。您可能应该使用javax.xml. valid.validator。

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import java.net.URL;
import org.xml.sax.SAXException;
//import java.io.File; // if you use File
import java.io.IOException;
...
URL schemaFile = new URL("http://host:port/filename.xsd");
// webapp example xsd: 
// URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd");
// local file example:
// File schemaFile = new File("/location/to/localfile.xsd"); // etc.
Source xmlFile = new StreamSource(new File("web.xml"));
SchemaFactory schemaFactory = SchemaFactory
    .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
  Schema schema = schemaFactory.newSchema(schemaFile);
  Validator validator = schema.newValidator();
  validator.validate(xmlFile);
  System.out.println(xmlFile.getSystemId() + " is valid");
} catch (SAXException e) {
  System.out.println(xmlFile.getSystemId() + " is NOT valid reason:" + e);
} catch (IOException e) {}

The schema factory constant is the string http://www.w3.org/2001/XMLSchema which defines XSDs. The above code validates a WAR deployment descriptor against the URL http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd but you could just as easily validate against a local file.

模式工厂常量是字符串http://www.w3.org/2001/XMLSchema,定义了XSDs。上面的代码针对URL http://java.sun.com/xml/ns/j2ee/webapp_2_4 .xsd验证WAR部署描述符,但是您也可以轻松地对本地文件进行验证。

You should not use the DOMParser to validate a document (unless your goal is to create a document object model anyway). This will start creating DOM objects as it parses the document - wasteful if you aren't going to use them.

您不应该使用DOMParser来验证文档(除非您的目标是创建文档对象模型)。这将在解析文档时开始创建DOM对象——如果您不打算使用它们,则会造成浪费。

#2


23  

Here's how to do it using Xerces2. A tutorial for this, here (req. signup).

以下是如何使用Xerces2进行此操作。这里有本教程(req)。注册)。

Original attribution: blatantly copied from here:

原创署名:公然抄袭:

import org.apache.xerces.parsers.DOMParser;
import java.io.File;
import org.w3c.dom.Document;

public class SchemaTest {
  public static void main (String args[]) {
      File docFile = new File("memory.xml");
      try {
        DOMParser parser = new DOMParser();
        parser.setFeature("http://xml.org/sax/features/validation", true);
        parser.setProperty(
             "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", 
             "memory.xsd");
        ErrorChecker errors = new ErrorChecker();
        parser.setErrorHandler(errors);
        parser.parse("memory.xml");
     } catch (Exception e) {
        System.out.print("Problem parsing the file.");
     }
  }
}

#3


19  

We build our project using ant, so we can use the schemavalidate task to check our config files:

我们使用ant构建项目,因此可以使用schemavalidate任务检查配置文件:

<schemavalidate> 
    <fileset dir="${configdir}" includes="**/*.xml" />
</schemavalidate>

Now naughty config files will fail our build!

现在淘气的配置文件将会使我们的构建失败!

http://ant.apache.org/manual/Tasks/schemavalidate.html

http://ant.apache.org/manual/Tasks/schemavalidate.html

#4


10  

I found this site to be helpful, too.

我发现这个网站也很有帮助。

http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html

http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html

It's the one that actually worked for me with a minimum of fuss.

这是对我最有效的方法。

#5


7  

Since this is a popular question, I would also like to point out that java can validate against a "referred to" xsd, for instance if the .xml file itself specifies an XSD, using xsi:SchemaLocation or xsi:noNamespaceSchemaLocation (or xsi for particular namespaces) as stated here:

由于这是一个流行的问题,我还想指出,java可以使用xsi:SchemaLocation或xsi:noNamespaceSchemaLocation(或xsi:特定名称空间)来验证“引用”xsd,例如.xml文件本身指定了xsd:

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd">
  ...

or SchemaLocation (always a list of namespace to xsd mappings)

或者SchemaLocation(始终是xsd映射的命名空间列表)

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:SchemaLocation="http://www.example.com/document http://www.example.com/document.xsd">
  ...

"If you create a schema without specifying a URL, file, or source, then the Java language creates one that looks in the document being validated to find the schema it should use. For example:"

如果您创建了一个模式而没有指定URL、文件或源,那么Java语言将创建一个模式,该模式将在被验证的文档中查找它应该使用的模式。例如:“

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

and this works for multiple namespaces, etc. The problem with this approach is that the xmlsns:xsi is probably a network location, so it'll go out and hit the network with each and every validation, not always optimal.

这种方法的问题是,xmlsns:xsi可能是一个网络位置,所以每次验证时它都会出去攻击网络,并不总是最优的。

Here's an example that validates an XML file against any XSD's it references (even if it has to pull them from the network):

下面的示例针对XSD的it引用验证XML文件(即使它必须从网络中提取它们):

  public static void verifyValidatesInternalXsd(String filename) throws Exception {
    InputStream xmlStream = new new FileInputStream(filename);
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);
    factory.setNamespaceAware(true);
    factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                 "http://www.w3.org/2001/XMLSchema");
    DocumentBuilder builder = factory.newDocumentBuilder();
    builder.setErrorHandler(new RaiseOnErrorHandler());
    builder.parse(new InputSource(xmlStream));
    xmlStream.close();
  }

  public static class RaiseOnErrorHandler implements ErrorHandler {
    public void warning(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void error(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void fatalError(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
  }

You can avoid pulling referenced XSD's from the network, even though the xml files reference url's, by specifying the xsd manually (see some other answers here) or by using an "XML catalog" style resolver. Spring apparently also can intercept the URL requests to serve local files for validations. Or you can set your own via setResourceResolver, ex:

您可以通过手动指定XSD(请参阅此处的一些其他答案)或使用“xml编目”样式解析器,避免从网络中提取引用的XSD,即使xml文件引用url是引用的。Spring显然也可以拦截URL请求,以提供本地文件的验证。或者你也可以通过setResourceResolver,例如:

Source xmlFile = new StreamSource(xmlFileLocation);
SchemaFactory schemaFactory = SchemaFactory
                                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setResourceResolver(new LSResourceResolver() {
  @Override
  public LSInput resolveResource(String type, String namespaceURI,
                                 String publicId, String systemId, String baseURI) {
    InputSource is = new InputSource(
                           getClass().getResourceAsStream(
                          "some_local_file_in_the_jar.xsd"));
                          // or lookup by URI, etc...
    return new Input(is); // for class Input see 
                          // https://*.com/a/2342859/32453
  }
});
validator.validate(xmlFile);

See also here for another tutorial.

请参见这里的另一个教程。

#6


4  

Using Java 7 you can follow the documentation provided in package description.

使用Java 7,您可以遵循包描述中提供的文档。

// parse an XML document into a DOM tree
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = parser.parse(new File("instance.xml"));

// 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("mySchema.xsd"));
Schema schema = factory.newSchema(schemaFile);

// create a Validator instance, which can be used to validate an instance document
Validator validator = schema.newValidator();

// validate the DOM tree
try {
    validator.validate(new DOMSource(document));
} catch (SAXException e) {
    // instance document is invalid!
}

#7


3  

One more answer: since you said you need to validate files you are generating (writing), you might want to validate content while you are writing, instead of first writing, then reading back for validation. You can probably do that with JDK API for Xml validation, if you use SAX-based writer: if so, just link in validator by calling 'Validator.validate(source, result)', where source comes from your writer, and result is where output needs to go.

还有一个答案:既然您说过您需要验证正在生成(写入)的文件,那么您可能希望在编写时验证内容,而不是先编写,然后再读取以进行验证。如果您使用基于sax的writer:如果可以,只需通过调用“validator”在validator中链接验证器。验证(源,结果)',源来自您的作者,结果是输出需要去的地方。

Alternatively if you use Stax for writing content (or a library that uses or can use stax), Woodstox can also directly support validation when using XMLStreamWriter. Here's a blog entry showing how that is done:

另外,如果您使用Stax来编写内容(或者使用或可以使用Stax的库),那么在使用XMLStreamWriter时,Woodstox也可以直接支持验证。这里有一个博客条目展示了这是如何做到的:

#8


2  

If you are generating XML files programatically, you may want to look at the XMLBeans library. Using a command line tool, XMLBeans will automatically generate and package up a set of Java objects based on an XSD. You can then use these objects to build an XML document based on this schema.

如果您正在程序化地生成XML文件,您可能需要查看XMLBeans库。使用命令行工具,XMLBeans将根据XSD自动生成并打包一组Java对象。然后,您可以使用这些对象来基于这个模式构建XML文档。

It has built-in support for schema validation, and can convert Java objects to an XML document and vice-versa.

它内置了对模式验证的支持,可以将Java对象转换为XML文档,反之亦然。

Castor and JAXB are other Java libraries that serve a similar purpose to XMLBeans.

Castor和JAXB是其他Java库,它们的用途与XMLBeans相似。

#9


2  

If you have a Linux-Machine you could use the free command-line tool SAXCount. I found this very usefull.

如果你有一台linux机器,你可以使用免费的命令行工具SAXCount。我发现这很有用。

SAXCount -f -s -n my.xml

It validates against dtd and xsd. 5s for a 50MB file.

它对dtd和xsd进行验证。5s用于50MB文件。

In debian squeeze it is located in the package "libxerces-c-samples".

在debian挤密中,它位于“libxerces-c-sample”包中。

The definition of the dtd and xsd has to be in the xml! You can't config them separately.

dtd和xsd的定义必须在xml中!不能单独配置它们。

#10


0  

Are you looking for a tool or a library?

你在找工具还是图书馆?

As far as libraries goes, pretty much the de-facto standard is Xerces2 which has both C++ and Java versions.

就库而言,实际上的标准是Xerces2,它有c++和Java版本。

Be fore warned though, it is a heavy weight solution. But then again, validating XML against XSD files is a rather heavy weight problem.

不过要注意的是,这是一个沉重的负担。但同样,根据XSD文件验证XML是一个相当重的问题。

As for a tool to do this for you, XMLFox seems to be a decent freeware solution, but not having used it personally I can't say for sure.

至于为您实现这一点的工具,XMLFox似乎是一个不错的免费软件解决方案,但我不能肯定地说,它并没有亲自使用它。

#11


0  

With JAXB, you could use the code below:

使用JAXB,您可以使用以下代码:

    @Test
public void testCheckXmlIsValidAgainstSchema() {
    logger.info("Validating an XML file against the latest schema...");

    MyValidationEventCollector vec = new MyValidationEventCollector();

    validateXmlAgainstSchema(vec, inputXmlFileName, inputXmlSchemaName, inputXmlRootClass);

    assertThat(vec.getValidationErrors().isEmpty(), is(expectedValidationResult));
}

private void validateXmlAgainstSchema(final MyValidationEventCollector vec, final String xmlFileName, final String xsdSchemaName, final Class<?> rootClass) {
    try (InputStream xmlFileIs = Thread.currentThread().getContextClassLoader().getResourceAsStream(xmlFileName);) {
        final JAXBContext jContext = JAXBContext.newInstance(rootClass);
        // Unmarshal the data from InputStream
        final Unmarshaller unmarshaller = jContext.createUnmarshaller();

        final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        final InputStream schemaAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xsdSchemaName);
        unmarshaller.setSchema(sf.newSchema(new StreamSource(schemaAsStream)));

        unmarshaller.setEventHandler(vec);

        unmarshaller.unmarshal(new StreamSource(xmlFileIs), rootClass).getValue(); // The Document class is the root object in the XML file you want to validate

        for (String validationError : vec.getValidationErrors()) {
            logger.trace(validationError);
        }
    } catch (final Exception e) {
        logger.error("The validation of the XML file " + xmlFileName + " failed: ", e);
    }
}

class MyValidationEventCollector implements ValidationEventHandler {
    private final List<String> validationErrors;

    public MyValidationEventCollector() {
        validationErrors = new ArrayList<>();
    }

    public List<String> getValidationErrors() {
        return Collections.unmodifiableList(validationErrors);
    }

    @Override
    public boolean handleEvent(final ValidationEvent event) {
        String pattern = "line {0}, column {1}, error message {2}";
        String errorMessage = MessageFormat.format(pattern, event.getLocator().getLineNumber(), event.getLocator().getColumnNumber(),
                event.getMessage());
        if (event.getSeverity() == ValidationEvent.FATAL_ERROR) {
            validationErrors.add(errorMessage);
        }
        return true; // you collect the validation errors in a List and handle them later
    }
}

#12


-2  

I had to validate an XML against XSD just one time, so I tried XMLFox. I found it to be very confusing and weird. The help instructions didn't seem to match the interface.

我只需要对XSD验证一次XML,所以我尝试了XMLFox。我发现它非常令人困惑和奇怪。帮助指令似乎与接口不匹配。

I ended up using LiquidXML Studio 2008 (v6) which was much easier to use and more immediately familiar (the UI is very similar to Visual Basic 2008 Express, which I use frequently). The drawback: the validation capability is not in the free version, so I had to use the 30 day trial.

最后,我使用了LiquidXML Studio 2008 (v6),它更容易使用,也更熟悉(UI与我经常使用的Visual Basic 2008 Express非常相似)。缺点:验证功能不在免费版本中,所以我不得不使用30天的测试。