Java JAXB编组到XML——当模式验证失败时,有没有办法处理它?

Java JAXB编组到XML——当模式验证失败时,有没有办法处理它?,java,xml,xsd,jaxb,marshalling,Java,Xml,Xsd,Jaxb,Marshalling,我正在使用JAXB,以便将一些对象打包/解包到XML文件中,以实现我想要实现的一个小型服务。现在,我的XML模式(.xsd文件)包含一些唯一的约束: <!--....--> <xs:unique name="uniqueValueID"> <xs:selector xpath="entry/value"/> <xs:field xpath="id"/> </xs:unique> <!--....--> 当模

我正在使用
JAXB
,以便将一些对象打包/解包到XML文件中,以实现我想要实现的一个小型服务。现在,我的XML模式(.xsd文件)包含一些
唯一的
约束:

<!--....-->
<xs:unique name="uniqueValueID">
    <xs:selector xpath="entry/value"/>
    <xs:field xpath="id"/>
</xs:unique>
<!--....-->
当模式有效时,目标文件将正常更新,但当验证失败时,文件将清空或数据不完整


我猜想问题在于封送处理程序打开了一个文件流,但是当验证失败时,它不能正确处理这种情况。有没有一种方法可以正确地处理这个问题,以便在验证失败时,不会对XML文件应用任何写入操作?

JAX-B封送员将对各种Java文件进行写入™ 输出接口。如果我想确保编组失败时不会将字节写入文件或其他固定实体,我将使用字符串缓冲区来包含编组过程的结果,然后写入缓冲区中包含的编组XML文档,如下所示:

     try
     {
        StringWriter output = new StringWriter ();
        JAXBContext jc = JAXBContext.newInstance (packageId);
        FileWriter savedAs;

        // Marshal the XML data to a string buffer here
        Marshaller marshalList = jc.createMarshaller ();
        marshalList.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshalList.marshal (toUpdate, output);

        // append the xml to the file to update here.
        savedAs = new FileWriter (new File (xmlFileName), true);
        savedAs.write (output.toString);
        savedAs.close();
     }
     catch (IOException iox)
     {
        String msg = "IO error on save: " + iox.getMessage ();
        throw new LocalException (msg, 40012, "UNKNOWN", iox);
     }
     catch (JAXBException jbx)
     {
        String msg = "Error writing definitions: " + jbx.getMessage ();
        throw new LocalException (msg, 40005, "UNKNOWN", jbx);
     }
  }
请注意,在本例中,如果封送处理失败,程序将永远不会创建输出文件,只会丢弃缓冲区字符串


对于一个稍微优雅但风险更大的解决方案,一个缓冲编写器(java.io.BufferedWriter),它允许创建它的调用方设置缓冲区大小。如果缓冲区大小超过文档大小,程序可能不会向文件写入任何内容,除非程序在流上调用close或flush。

savedAs=new FileWriter(new file(xmlFileName),true)将附加不需要的数据。回答更新。合理的想法。但是,跳过字符串并使用字节(写入ByteArrayOutputStream),这样就不会在过程中破坏xml编码。写入临时文件,如果成功,则重命名为原始文件。这是“原子式”文件写入的常用技术。
     try
     {
        StringWriter output = new StringWriter ();
        JAXBContext jc = JAXBContext.newInstance (packageId);
        FileWriter savedAs;

        // Marshal the XML data to a string buffer here
        Marshaller marshalList = jc.createMarshaller ();
        marshalList.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshalList.marshal (toUpdate, output);

        // append the xml to the file to update here.
        savedAs = new FileWriter (new File (xmlFileName), true);
        savedAs.write (output.toString);
        savedAs.close();
     }
     catch (IOException iox)
     {
        String msg = "IO error on save: " + iox.getMessage ();
        throw new LocalException (msg, 40012, "UNKNOWN", iox);
     }
     catch (JAXBException jbx)
     {
        String msg = "Error writing definitions: " + jbx.getMessage ();
        throw new LocalException (msg, 40005, "UNKNOWN", jbx);
     }
  }