将 Java 对象转换为 XML 字符串

Posted

技术标签:

【中文标题】将 Java 对象转换为 XML 字符串【英文标题】:Convert Java object to XML string 【发布时间】:2015-01-13 13:50:57 【问题描述】:

是的,是的,我知道有人就这个话题提出了很多问题。但我仍然找不到解决问题的方法。我有一个属性注释的 Java 对象。例如客户,like in this example。我想要它的字符串表示。 Google 建议将 JAXB 用于此类目的。但在所有示例中,创建的 XML 文件都会打印到文件或控制台,如下所示:

File file = new File("C:\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

jaxbMarshaller.marshal(customer, file);
jaxbMarshaller.marshal(customer, System.out);

但我必须使用这个对象并以 XML 格式通过网络发送。所以我想得到一个代表 XML 的字符串。

String xmlString = ...
sendOverNetwork(xmlString);

我该怎么做?

【问题讨论】:

【参考方案1】:

您可以使用以Writer 作为参数的编组器方法进行编组:

marshal(Object,Writer)

并传递一个可以构建字符串对象的实现

直接已知的子类: BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

调用它的toString方法来获取实际的String值。

这样做:

StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(customer, sw);
String xmlString = sw.toString();

【讨论】:

StringWriter 已经很老了。在幕后,它使用StringBuffer,其中更快的方法是使用StringBuilder,但在第一次制作StringWriter时并不存在。因此,每次调用sw.toString() 都意味着同步。如果您正在寻找性能,那就太糟糕了。 @peterh 这里的所有答案都使用 StringWriter。你会建议什么? jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);使用它来获取 XML 的确切结构。 对于 org.springframework.oxm.jaxb.Jaxb2Marshaller,您可以使用:final StringResult result = new StringResult(); jaxb2Marshaller.marshal(customer, result); String xmlString = result.toString();【参考方案2】:

一个方便的选择是使用javax.xml.bind.JAXB:

StringWriter sw = new StringWriter();
JAXB.marshal(customer, sw);
String xmlString = sw.toString();

[reverse] 过程(解组)将是:

Customer customer = JAXB.unmarshal(new StringReader(xmlString), Customer.class);

在这种方法中不需要处理已检查的异常。

【讨论】:

这不会复制只有 getter 的字段【参考方案3】:

正如 A4L 提到的,你可以使用 StringWriter。此处提供示例代码:

private static String jaxbObjectToXML(Customer customer) 
    String xmlString = "";
    try 
        JAXBContext context = JAXBContext.newInstance(Customer.class);
        Marshaller m = context.createMarshaller();

        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // To format XML

        StringWriter sw = new StringWriter();
        m.marshal(customer, sw);
        xmlString = sw.toString();

     catch (JAXBException e) 
        e.printStackTrace();
    

    return xmlString;

【讨论】:

StringWriter 中不需要 m.marshal(customer, System.out);【参考方案4】:

您可以将其编组为 StringWriter 并抓住其字符串。来自toString()

【讨论】:

@KickButtowski:答案的基本部分就是使用StringWriter。该链接只是文档。 请添加一些解释,很高兴我删除了我的反对票。 :) 你可以把它作为评论放在旁边 你能提供一个例子吗? @Bob:创建一个StringWriter,将其传递给marshal(),调用toString() @Bob 这个答案实际上就足够了。请学习如何研究 API,在这个例子中 Marshaller 有几个 marshal 重载方法,只要看看它们的参数和它们的作用,你就会找到答案。【参考方案5】:

测试和工作 Java 代码将 java 对象转换为 XML:

Customer.java

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement
public class Customer 

    String name;
    int age;
    int id;
    String desc;
    ArrayList<String> list;

    public ArrayList<String> getList()
    
        return list;
    

    @XmlElement
    public void setList(ArrayList<String> list)
    
        this.list = list;
    

    public String getDesc()
    
        return desc;
    

    @XmlElement
    public void setDesc(String desc)
    
        this.desc = desc;
    

    public String getName() 
        return name;
    

    @XmlElement
    public void setName(String name) 
        this.name = name;
    

    public int getAge() 
        return age;
    

    @XmlElement
    public void setAge(int age) 
        this.age = age;
    

    public int getId() 
        return id;
    

    @XmlAttribute
    public void setId(int id) 
        this.id = id;
    

createXML.java

import java.io.StringWriter;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;


public class createXML 

    public static void main(String args[]) throws Exception
    
        ArrayList<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        Customer c = new Customer();
        c.setAge(45);
        c.setDesc("some desc ");
        c.setId(23);
        c.setList(list);
        c.setName("name");
        JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter sw = new StringWriter();
        jaxbMarshaller.marshal(c, sw);
        String xmlString = sw.toString();
        System.out.println(xmlString);
    


【讨论】:

一般添加只包含代码而没有解释的答案是不被接受的【参考方案6】:

在 Java 中将 Object 转换为 XML

客户.java

package com;

import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
*
* @author ABsiddik
*/

@XmlRootElement
public class Customer 

int id;
String name;
int age;

String address;
ArrayList<String> mobileNo;


 public int getId() 
    return id;


@XmlAttribute
public void setId(int id) 
    this.id = id;


public String getName() 
    return name;


@XmlElement
public void setName(String name) 
    this.name = name;


public int getAge() 
    return age;


@XmlElement
public void setAge(int age) 
    this.age = age;


public String getAddress() 
    return address;


@XmlElement
public void setAddress(String address) 
    this.address = address;


public ArrayList<String> getMobileNo() 
    return mobileNo;


@XmlElement
public void setMobileNo(ArrayList<String> mobileNo) 
    this.mobileNo = mobileNo;




ConvertObjToXML.java

package com;

import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

/**
*
* @author ABsiddik
*/
public class ConvertObjToXML 

public static void main(String args[]) throws Exception

    ArrayList<String> numberList = new ArrayList<>();
    numberList.add("01942652579");
    numberList.add("01762752801");
    numberList.add("8800545");

    Customer c = new Customer();

    c.setId(23);
    c.setName("Abu Bakar Siddik");
    c.setAge(45);
    c.setAddress("Dhaka, Bangladesh");
    c.setMobileNo(numberList);

    File file = new File("C:\\Users\\NETIZEN-ONE\\Desktop \\customer.xml");
    JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    jaxbMarshaller.marshal(c, file);// this line create customer.xml file in specified path.

    StringWriter sw = new StringWriter();
    jaxbMarshaller.marshal(c, sw);
    String xmlString = sw.toString();

    System.out.println(xmlString);



试试这个例子..

【讨论】:

【参考方案7】:

使用 ByteArrayOutputStream

public static String printObjectToXML(final Object object) throws TransformerFactoryConfigurationError,
        TransformerConfigurationException, SOAPException, TransformerException

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    XMLEncoder xmlEncoder = new XMLEncoder(baos);
    xmlEncoder.writeObject(object);
    xmlEncoder.close();

    String xml = baos.toString();
    System.out.println(xml);

    return xml.toString();

【讨论】:

【参考方案8】:

我采用了 JAXB.marshal 实现并添加了 jaxb.fragment=true 以删除 XML 序言。即使没有 XmlRootElement 批注,此方法也可以处理对象。这也会引发未经检查的 DataBindingException。

public static String toXmlString(Object o) 
    try 
        Class<?> clazz = o.getClass();
        JAXBContext context = JAXBContext.newInstance(clazz);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); // remove xml prolog
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // formatted output

        final QName name = new QName(Introspector.decapitalize(clazz.getSimpleName()));
        JAXBElement jaxbElement = new JAXBElement(name, clazz, o);

        StringWriter sw = new StringWriter();
        marshaller.marshal(jaxbElement, sw);
        return sw.toString();

     catch (JAXBException e) 
        throw new DataBindingException(e);
    

如果编译器警告困扰您,这里是模板化的两个参数版本。

public static <T> String toXmlString(T o, Class<T> clazz) 
    try 
        JAXBContext context = JAXBContext.newInstance(clazz);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); // remove xml prolog
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // formatted output

        QName name = new QName(Introspector.decapitalize(clazz.getSimpleName()));
        JAXBElement jaxbElement = new JAXBElement<>(name, clazz, o);

        StringWriter sw = new StringWriter();
        marshaller.marshal(jaxbElement, sw);
        return sw.toString();

     catch (JAXBException e) 
        throw new DataBindingException(e);
    

【讨论】:

【参考方案9】:

这是一个用于编组和解组对象的实用程序类。在我的例子中,它是一个嵌套类,所以我将它设为静态 JAXBUtils。

import javax.xml.bind.JAXB;
import java.io.StringReader;
import java.io.StringWriter;

public class JAXBUtils

    /**
     * Unmarshal an XML string
     * @param xml     The XML string
     * @param type    The JAXB class type.
     * @return The unmarshalled object.
     */
    public <T> T unmarshal(String xml, Class<T> type)
    
        StringReader reader = new StringReader(xml);
        return javax.xml.bind.JAXB.unmarshal(reader, type);
    

    /**
     * Marshal an Object to XML.
     * @param object    The object to marshal.
     * @return The XML string representation of the object.
     */
    public String marshal(Object object)
    
        StringWriter stringWriter = new StringWriter();
        JAXB.marshal(object, stringWriter);
        return stringWriter.toString();
    

【讨论】:

【参考方案10】:

下面是Java类的一个例子,不同的注释集生成xml,CDATA和JaxB代码生成XML。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="customer")
public class Customer 
   
   @XmlElement(name = "first-name")
   String firstName;
   @XmlElement(name = "last-name")
   String lastName;
   
   @XmlElement(name= "customer-address")
   private Address address;
   
   @XmlElement(name= "bio")
   @XmlJavaTypeAdapter(AdapterCDATA.class)
   private Biography bio;



@XmlAccessorType(XmlAccessType.FIELD)
public class Address 
   
   @XmlElement(name = "house-number")
   String houseNumber;
   @XmlElement(name = "address-line-1")
   String addLine1;
   
   @XmlElement(name = "address-line-2")
   String addLine2;
   
  

 

适配器类

    public class AdaptorCDATA extends XmlAdapter<String, String> 

    @Override
    public String marshal(String arg0) throws Exception 
        return "<![CDATA[" + arg0 + "]]>";
    
    @Override
    public String unmarshal(String arg0) throws Exception 
        return arg0;
    

生成 XML 的 JAXB 代码

  public String xmlStringForCustomer(Customer customer) 
 
   JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
    Marshaller marshaller = jaxbContext.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    
    StringWriter writer = new StringWriter();
    marshaller.marshal(customer,sw);
    return sw.toString();

Above Code 将生成如下所示的 xml

<customer>
 <first-name></first-name>
 <last-name></last-name>
 <customer-address> 
     <house-number></house-number>
     <address-line-1></address-line-1>
     <address-line-2></address-line-2>
 </customer-address>
 <bio>
   <![CDATA[ **bio data will come here**]]>
 </bio>
< /customer>

【讨论】:

【参考方案11】:

创建 XML Stirng 的一些通用代码

object --> 是将其转换为 XML 的 Java 类name --> 只是名称空间之类的东西 - 用于区分

public static String convertObjectToXML(Object object,String name) 
          try 
              StringWriter stringWriter = new StringWriter();
              JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
              Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
              jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
              QName qName = new QName(object.getClass().toString(), name);
              Object root = new JAXBElement<Object>(qName,java.lang.Object.class, object);
              jaxbMarshaller.marshal(root, stringWriter);
              String result = stringWriter.toString();
              System.out.println(result);
              return result;
        catch (Exception e) 
            e.printStackTrace();
        
        return null;
    

【讨论】:

【参考方案12】:

Underscore-java 可以在构建器的帮助下构造 XML 字符串。

    class Customer 
        String name;
        int age;
        int id;
    
    Customer customer = new Customer();
    customer.name = "John";
    customer.age = 30;
    customer.id = 12345;

    String xml = U.objectBuilder().add("customer", U.objectBuilder()
        .add("name", customer.name)
        .add("age", customer.age)
        .add("id", customer.id)).toXml();

    // <?xml version="1.0" encoding="UTF-8"?>
    //    <customer>
    //      <name>John</name>
    //      <age number="true">30</age>
    //      <id number="true">12345</id>
    //    </customer>

【讨论】:

【参考方案13】:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

private String generateXml(Object obj, Class objClass) throws JAXBException 
        JAXBContext jaxbContext = JAXBContext.newInstance(objClass);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter sw = new StringWriter();
        jaxbMarshaller.marshal(obj, sw);
        return sw.toString();
    

【讨论】:

【参考方案14】:

使用此函数将 Object 转换为 xml 字符串 (应该叫convertToXml(sourceObject, Object.class);)-->

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;

public static <T> String convertToXml(T source, Class<T> clazz) throws JAXBException 
    String result;
    StringWriter sw = new StringWriter();
    JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    QName qName = new QName(StringUtils.uncapitalize(clazz.getSimpleName()));
    JAXBElement<T> root = new JAXBElement<T>(qName, clazz, source);
    jaxbMarshaller.marshal(root, sw);
    result = sw.toString();
    return result;

使用此函数将xml字符串转换回Object --> (应该叫createObjectFromXmlString(xmlString, Object.class)

public static <T> T createObjectFromXmlString(String xml, Class<T> clazz) throws JAXBException, IOException

    T value = null;
    StringReader reader = new StringReader(xml); 
    JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    JAXBElement<T> rootElement=jaxbUnmarshaller.unmarshal(new StreamSource(reader),clazz);
    value = rootElement.getValue();
    return value;

【讨论】:

以上是关于将 Java 对象转换为 XML 字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何在java中将String转换为DOM Document对象?

将对象列表转换为 xml 字符串

通过JAXB完成Java对象与XML之间的转换

将对象转换为 XML 字符串

将 XML 转换为动态 C# 对象

Android:将 Json 对象转换为 Strings.xml