Java JAXB如何动态生成模式以立即使用它进行验证?

Java JAXB如何动态生成模式以立即使用它进行验证?,java,xml,validation,jaxb,xsd,Java,Xml,Validation,Jaxb,Xsd,我花了很长时间试图弄清楚如何验证XML文件,并且我已经让它使用预先生成的XSD模式。然而,我希望在不创建文件的情况下动态生成一个模式,基于我指定的注释类,我尝试不为SchemaFactory指定任何参数,但它似乎只是创建了一个空模式(参见下面的注释) 下面是我用于JAXB读取和写入XML文件的两个类 这是XMLTranslationWrapper类的代码: @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(namespace = "my

我花了很长时间试图弄清楚如何验证XML文件,并且我已经让它使用预先生成的XSD模式。然而,我希望在不创建文件的情况下动态生成一个模式,基于我指定的注释类,我尝试不为SchemaFactory指定任何参数,但它似乎只是创建了一个空模式(参见下面的注释)

下面是我用于JAXB读取和写入XML文件的两个类

这是XMLTranslationWrapper类的代码:

@XmlAccessorType(XmlAccessType.FIELD)

@XmlRootElement(namespace = "my.package.namespace")
public class XMLTranslationWrapper {

      @XmlElementWrapper(name   = "TRANSLATIONS")
      @XmlElement(name          = "TRANSL")
      public ArrayList<XMLTranslationNode> translations;

      public XMLTranslationWrapper(){
          translations = new ArrayList<XMLTranslationNode>();
      }

      public void setTranslations(ArrayList<XMLTranslationNode> translations){
          this.translations = translations;
      }

      public XMLTranslationNode getTranslation(String code){
          for(XMLTranslationNode transl : translations){
              if(transl.getCode().equals(code))
                  return transl;
          }
        return null;
      }

      public void addTranslation(XMLTranslationNode translation){
          this.translations.add(translation);
      }
}
这是我用来生成预生成的XSD模式的代码:

public class generateSchema {

    public static void main(String[] args) {
        JAXBContext jaxbContext;
        try {
            jaxbContext = JAXBContext.newInstance(XMLTranslationWrapper.class);
            SchemaOutputResolver sor = new MySchemaOutputResolver();
            jaxbContext.generateSchema(sor);
        } catch (JAXBException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static class MySchemaOutputResolver extends SchemaOutputResolver {

        public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException {
            File file = new File(suggestedFileName);
            StreamResult result = new StreamResult(file);
            System.out.println(file.toURI().toURL().toString());
            result.setSystemId(file.toURI().toURL().toString());
            return result;
        }

    }

}
最后,这里是一个可用于测试代码的示例XML:

<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
<ns2:xmlTranslationWrapper xmlns:ns2="my.package.namespace">
    <TRANSLATIONS>
        <TRANSL CODE="123">
            <SEVERITY>Information</SEVERITY>
            <TRANSLATION>ABC</TRANSLATION>
        </TRANSL>
    </TRANSLATIONS>
</ns2:xmlTranslationWrapper>

问询处
基础知识

如何在不创建与使用预生成的XSD模式等效的文件的情况下动态生成XSD模式?

如承诺的那样。想法很简单:

  • 首先将模式生成为DOM结果
  • 程序将从生成的DOM中解析它
  • 最后,用于验证
我认为你做得再好不过了。JAXB的
schemagen
内部结构似乎与
javax.xml.validation.Schema
不兼容。因此,创建DOM并对其进行解析是最简单的方法

:


如承诺的那样。想法很简单:

  • 首先将模式生成为DOM结果
  • 程序将从生成的DOM中解析它
  • 最后,用于验证
我认为你做得再好不过了。JAXB的
schemagen
内部结构似乎与
javax.xml.validation.Schema
不兼容。因此,创建DOM并对其进行解析是最简单的方法

:


我感到困惑的是——为什么您认为模式工厂会“动态地”为您生成一个模式?我认为它只是创建了一个空的模式实例,那么为什么你认为它会验证任何东西呢?@lexicore我没有很好地阅读模式工厂的文档,所以我可能完全理解错了。如果是这样的话,我将如何继续动态地进行呢?谢谢。好的,所以问题归结为以下几点:如何动态生成模式并立即使用它进行验证。对的请更新问题。这是可能的,我到时候会回答。@lexicore好的,谢谢,我现在更新了我的问题。我困惑的是-为什么您认为模式工厂会“动态”为您生成模式?我认为它只是创建了一个空的模式实例,那么为什么你认为它会验证任何东西呢?@lexicore我没有很好地阅读模式工厂的文档,所以我可能完全理解错了。如果是这样的话,我将如何继续动态地进行呢?谢谢。好的,所以问题归结为以下几点:如何动态生成模式并立即使用它进行验证。对的请更新问题。这是可能的,我会回答。@lexicore好的,谢谢,我现在更新了我的问题。非常感谢,如果你不介意我有一个简单的问题,使用这种方法会比从我的应用程序的资源文件夹加载XSD架构更好吗?我绝对不会为了验证而进行动态架构生成。我会在编译时生成模式作为资源,它将用于参考和契约目的。非常感谢,如果你不介意的话,我有一个简单的问题,使用这种方法会比从我的应用程序的资源文件夹中加载XSD模式更好吗?我绝对不会为了验证而进行动态模式生成。我将在编译时生成模式作为资源,它将用于引用和契约目的。
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
<ns2:xmlTranslationWrapper xmlns:ns2="my.package.namespace">
    <TRANSLATIONS>
        <TRANSL CODE="123">
            <SEVERITY>Information</SEVERITY>
            <TRANSLATION>ABC</TRANSLATION>
        </TRANSL>
    </TRANSLATIONS>
</ns2:xmlTranslationWrapper>
public class DynamicSchemaTest {

    @XmlRootElement
    public static class A {
        @XmlAttribute(required = true)
        public String name;

        public A() {
        }

        public A(String name) {
            this.name = name;
        }
    }

    @Test(expected = MarshalException.class)
    public void generatesAndUsesSchema() throws JAXBException, IOException,
            SAXException {
        final JAXBContext context = JAXBContext.newInstance(A.class);
        final DOMResult result = new DOMResult();
        result.setSystemId("schema.xsd");
        context.generateSchema(new SchemaOutputResolver() {
            @Override
            public Result createOutput(String namespaceUri,
                    String suggestedFileName) {
                return result;
            }
        });

        @SuppressWarnings("deprecation")
        final SchemaFactory schemaFactory = SchemaFactory
                .newInstance(WellKnownNamespace.XML_SCHEMA);
        final Schema schema = schemaFactory.newSchema(new DOMSource(result
                .getNode()));

        final Marshaller marshaller = context.createMarshaller();
        marshaller.setSchema(schema);
        // Works
        marshaller.marshal(new A("works"), System.out);
        // Fails
        marshaller.marshal(new A(null), System.out);
    }
}