JAXB以不同的方式将XML封送到OutputStream和StringWriter [英] JAXB marshals XML differently to OutputStream vs. StringWriter

查看:115
本文介绍了JAXB以不同的方式将XML封送到OutputStream和StringWriter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果已经回答,我很抱歉,但是我一直在使用的搜索术语(即 JAXB @XmlAttribute压缩 JAXB XML编组到字符串不同的结果 )没有任何结果。

I apologize if this has been answered, but the search terms I have been using (i.e. JAXB @XmlAttribute condensed or JAXB XML marshal to String different results) aren't coming up with anything.

我正在使用JAXB取消/编组用<$ c $注释的对象c> @XmlElement 和 @XmlAttribute 注释。我有一个格式化程序类,它提供了两个方法 - 一个包装marshal方法并接受对象编组和一个 OutputStream ,另一个只接受该对象并返回XML输出作为一个字符串。不幸的是,这些方法不能为相同的对象提供相同的输出。封送到文件时,内部标有 @XmlAttribute 的简单对象字段打印为:

I am using JAXB to un/marshal objects annotated with @XmlElement and @XmlAttribute annotations. I have a formatter class which provides two methods -- one wraps the marshal method and accepts the object to marshal and an OutputStream, the other just accepts the object and returns the XML output as a String. Unfortunately, these methods do not provide the same output for the same objects. When marshaling to a file, simple object fields internally marked with @XmlAttribute are printed as:

<element value="VALUE"></element>

当编组到字符串时,它们是:

while when marshaling to a String, they are:

<element value="VALUE"/>

我更喜欢这两种情况的第二种格式,但我很好奇如何控制差异并且无论如何都会满足于他们。我甚至创建了一个静态编组器,两种方法都使用它来消除不同的实例值。格式代码如下:

I would prefer the second format for both cases, but I am curious as to how to control the difference, and would settle for them being the same regardless. I even created one static marshaller that both methods use to eliminate different instance values. The formatting code follows:

/** Marker interface for classes which are listed in jaxb.index */
public interface Marshalable {}







/** Local exception class */
public class XMLMarshalException extends BaseException {}







/** Class which un/marshals objects to XML */
public class XmlFormatter {
    private static Marshaller marshaller = null;
    private static Unmarshaller unmarshaller = null;

    static {
        try {
            JAXBContext context = JAXBContext.newInstance("path.to.package");
            marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

            unmarshaller = context.createUnmarshaller();
        } catch (JAXBException e) {
            throw new RuntimeException("There was a problem creating a JAXBContext object for formatting the object to XML.");
        }
    }

    public void marshal(Marshalable obj, OutputStream os) throws XMLMarshalException {
        try {
            marshaller.marshal(obj, os);
        } catch (JAXBException jaxbe) {
            throw new XMLMarshalException(jaxbe);
        }
    }

    public String marshalToString(Marshalable obj) throws XMLMarshalException {
        try {
            StringWriter sw = new StringWriter();
            return marshaller.marshal(obj, sw);
        } catch (JAXBException jaxbe) {
            throw new XMLMarshalException(jaxbe);
        }
    }
}







/** Example data */
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
public class Data {

    @XmlAttribute(name = value)
    private String internalString;
}







/** Example POJO */
@XmlType
@XmlRootElement(namespace = "project/schema")
@XmlAccessorType(XmlAccessType.FIELD)
public class Container implements Marshalable {

    @XmlElement(required = false, nillable = true)
    private int number;

    @XmlElement(required = false, nillable = true)
    private String word;

    @XmlElement(required = false, nillable = true)
    private Data data;
}

调用 marshal(容器,新FileOutputStream)的结果(output.xml)) marshalToString(容器)如下:

输出到文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
<ns2:container xmlns:ns2="project/schema">  
    <number>1</number>  
    <word>stackoverflow</word>  
    <data value="This is internal"></data>  
</ns2:container>

输出到字符串

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
<ns2:container xmlns:ns2="project/schema">  
    <number>1</number>  
    <word>stackoverflow</word>  
    <data value="This is internal"/>  
</ns2:container>


推荐答案

看起来这可能是JAXB中的bug 。查看源代码,调用marshal()会根据输出/编写器类型参数创建不同的编写器:

Looks like this might be a "bug" in JAXB. Looking at the source, the calls for marshal() create different writers based on the output/writer type parameter:

public void marshal(Object obj, OutputStream out, NamespaceContext inscopeNamespace) throws JAXBException {
    write(obj, createWriter(out), new StAXPostInitAction(inscopeNamespace,serializer));
}

public void marshal(Object obj, XMLStreamWriter writer) throws JAXBException {
    write(obj, XMLStreamWriterOutput.create(writer,context), new StAXPostInitAction(writer,serializer));
}

编写器的实现在处理空元素方面有所不同。以上代码来自:

The implementations of the writers is different with regards to how they handle "empty elements". The above code is from:

jaxb-ri\runtime\src\com\sun\xml\bind\v2 \runtime \ MarshallerImpl.java。

jaxb-ri\runtime\src\com\sun\xml\bind\v2\runtime\MarshallerImpl.java.

您正在创建的两个作者是:

The two writers you are creating are:

jaxb-ri \ runun src\com\sun\xml\bind\v2\runtime\output\UTF8XmlOutput.java

jaxb-ri\runtime\src\com\sun\xml\bind\v2\runtime\output\UTF8XmlOutput.java

jaxb-ri\runtime\ src\com\sun\xml\bind\v2 \runtime\output\XMLStreamWriterOutput.java

jaxb-ri\runtime\src\com\sun\xml\bind\v2\runtime\output\XMLStreamWriterOutput.java

这篇关于JAXB以不同的方式将XML封送到OutputStream和StringWriter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆