【问题标题】:Convert Java object to XML string将 Java 对象转换为 XML 字符串
【发布时间】: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);

我该怎么做?

【问题讨论】:

    标签: java xml jaxb


    【解决方案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;
                    }
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2019-04-10
                      • 2012-07-11
                      • 2011-03-12
                      • 1970-01-01
                      • 1970-01-01
                      • 2013-06-20
                      相关资源
                      最近更新 更多