การทำให้อนุกรม XML ใน Java? [ปิด]


104

อะนาล็อก Java ของการทำให้อนุกรม XML ของ. NET คืออะไร


7
อ่าช่วงเวลาอันรุ่งโรจน์เมื่อมีคำถามแบบซับเดียวเช่นนี้ได้รับการต้อนรับใน SO มีประโยชน์มาก หากไม่มีสิ่งที่ "คุณพยายามทำอะไร" / "ให้รายละเอียด" เรื่องไร้สาระที่คนทั่วไปชอบอ่านในวันนี้
GOTO 0

คำตอบ:


81

2008 คำตอบ Java API "อย่างเป็นทางการ" สำหรับตอนนี้คือ JAXB - Java API สำหรับการเชื่อม XML ดูการสอนโดยออราเคิล การใช้งานอ้างอิงอยู่ที่http://jaxb.java.net/

2018 ปรับปรุง ทราบว่าชวา EE และ CORBA โมดูลจะเลิกใช้ใน SE ใน JDK9 และจะถูกลบออกจาก SE ใน JDK11 ดังนั้นในการใช้ JAXB จึงจำเป็นต้องอยู่ในสภาพแวดล้อมระดับองค์กรที่มีอยู่ซึ่งรวมอยู่ในเซิร์ฟเวอร์แอปเช่นของคุณหรือคุณจะต้องนำเข้ามาด้วยตนเอง


2
ใช่แล้ว JAXB เป็นตัวเลือกที่ดีที่สุด!
ivan_ivanovich_ivanoff

1
JAXB ถูกลบออกจากการแจกแจง Java มาตรฐานตั้งแต่ Java 10 ซึ่งทำให้ตอนนี้เป็นไลบรารีที่คุณต้องรวมกับแอปพลิเคชันของคุณหากคุณต้องการเว้นแต่คุณจะดำเนินการในบริบทที่รวมกลุ่มไว้ให้คุณแล้ว
Theodore Murdock

69

XStreamค่อนข้างดีในการทำให้วัตถุเป็นอนุกรมเป็น XML โดยไม่ต้องกำหนดค่าและเงินมาก (อยู่ภายใต้ใบอนุญาต BSD)

เราใช้มันในโปรเจ็กต์หนึ่งของเราเพื่อแทนที่ java-serialization แบบเดิม ๆ และมันก็ใช้งานได้เกือบหมดกล่อง


3
มีประโยชน์มากมันอาจมีปัญหากับโครงสร้างต้นไม้ที่สมบูรณ์เช่น JGraph กับวัตถุโหนดที่ไม่ใช่สตริง
mikek3332002

วิธีแก้ปัญหาอื่น ๆ ที่ง่ายขึ้นและดีขึ้น
daitangio

ฉันชอบ XStream สิ่งเดียวคือฉันไม่เข้าใจว่าทำไมจึงเพิ่มอักขระก่อน XML จริง
James P.

17

โครงการ "อนุกรม XML อย่างง่าย"

คุณอาจต้องการที่จะมองไปที่อันดับที่เรียบง่าย XMLโครงการ มันเป็นสิ่งที่ใกล้เคียงที่สุดที่ฉันพบกับ System.Xml.Serialization ใน. Net


อย่างไรก็ตามต้องมีคำอธิบายประกอบการทำแผนที่สำหรับแต่ละฟิลด์
mP.

1
ไม่จริงฉันไม่ต้องการ คุณสามารถเปลี่ยนพฤติกรรมเริ่มต้นและจะใช้เฉพาะฟิลด์ปัจจุบัน
Konstantin Milyutin

1
ขอรับรอง"Simple"ด้วยใจจริงเช่นกัน ฉันเคยใช้มันกับสองโปรเจ็กต์ที่ประสบความสำเร็จอย่างมาก "ง่าย" เป็นที่แน่นอนมากง่ายที่ JAXB เหมาะสมที่สุดเมื่อคุณมีความต้องการที่ค่อนข้างเรียบง่าย: มีวัตถุที่ต้องเขียนลงในที่จัดเก็บเพื่อนำกลับมาเติมน้ำเป็นวัตถุอีกครั้งในภายหลัง JAXB มีคุณสมบัติและความยืดหยุ่นมากกว่า แต่มันเป็นประเภท "80/20" โดยส่วนใหญ่ในโครงการส่วนใหญ่คุณอาจต้องการเพียงคุณสมบัติส่วนย่อยง่ายๆ
Basil Bourque

ใช้งานได้ดีถ้าคุณต้องการเพียงแค่การทำแผนที่ 1: 1 หากคลาสของคุณมีวิวัฒนาการและคุณยังคงต้องยกเลิกการกำหนดค่า XML เก่าคุณจะพบปัญหาเนื่องจากทั้งเอกสารประกอบและข้อความแสดงข้อผิดพลาดค่อนข้างคลุมเครือ การวินิจฉัยปัญหามักทำได้ แต่การหาวิธีแก้ไขอาจใช้เวลาหลายวัน
toolforger

13

JAXB เป็นส่วนหนึ่งของ JDK standard edition เวอร์ชัน 1.6+ ดังนั้นจึงFREEไม่มีไลบรารีเพิ่มเติมให้ดาวน์โหลดและจัดการ ตัวอย่างง่ายๆสามารถพบได้ที่นี่

XStream ดูเหมือนจะตายไปแล้ว อัปเดตล่าสุดเมื่อวันที่ 6 ธันวาคม 2008 Simpleดูเหมือนว่าจะง่ายและง่ายกว่า JAXB แต่ฉันไม่พบข้อมูลการอนุญาตให้ใช้สิทธิ์ใด ๆ เพื่อประเมินการใช้งานในองค์กร


4
XStream ยังไม่ตายมันเป็นผู้ใหญ่และมีเสถียรภาพ - หมายความว่าไม่มีอะไรให้เพิ่มในฟังก์ชันหลัก เช่นเดียวกับการใช้งานอ้างอิง JAXB ซึ่งมีกิจกรรมไม่มากนักในช่วงสองสามปีที่ผ่านมา
StaxMan

9

ควรค่าแก่การกล่าวถึงว่าตั้งแต่เวอร์ชัน 1.4 Java มีคลาส java.beans.XMLEncoder และ java.beans.XMLDecoder คลาสเหล่านี้ทำการเข้ารหัส XML ซึ่งอย่างน้อยก็เทียบได้กับ XML Serialization และในบางสถานการณ์อาจทำเคล็ดลับสำหรับคุณ

หากคลาสของคุณยึดติดกับข้อกำหนด JavaBeans สำหรับ getters และ setters วิธีนี้ใช้งานง่ายและคุณไม่จำเป็นต้องมีสคีมา ด้วยคำเตือนต่อไปนี้:

  • เช่นเดียวกับการทำให้เป็นอนุกรม Java ปกติ
    • การเข้ารหัสและถอดรหัสทำงานบน InputStream และ OutputStream
    • กระบวนการนี้ใช้เมธอด writeObject และ readObject ที่เหมือนกัน
  • ตรงกันข้ามกับการทำให้เป็นอนุกรมของ Java ปกติ
    • การเข้ารหัส แต่ยังถอดรหัสทำให้ตัวสร้างและตัวเริ่มต้นถูกเรียกใช้
    • การเข้ารหัสและการถอดรหัสทำงานได้ไม่ว่าชั้นเรียนของคุณจะใช้งานต่อเนื่องได้หรือไม่ก็ตาม
    • ไม่นำตัวดัดแปลงชั่วคราวมาพิจารณา
    • ใช้งานได้เฉพาะสำหรับชั้นเรียนสาธารณะที่มีผู้ก่อสร้างสาธารณะ

ตัวอย่างเช่นรับคำประกาศต่อไปนี้:

public class NPair {
  public NPair() { }
  int number1 = 0;
  int number2 = 0;
  public void setNumber1(int value) { number1 = value;}
  public int getNumber1() { return number1; }
  public void setNumber2(int value) { number2 = value; }
  public int getNumber2() {return number2;}
}

การเรียกใช้รหัสนี้:

NPair fe = new NPair();
fe.setNumber1(12);
fe.setNumber2(13);
FileOutputStream fos1 = new FileOutputStream("d:\\ser.xml");
java.beans.XMLEncoder xe1 = new java.beans.XMLEncoder(fos1);
xe1.writeObject(fe);
xe1.close();

จะส่งผลให้เกิดไฟล์ต่อไปนี้:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_02" class="java.beans.XMLDecoder">
 <object class="NPair">
  <void property="number1">
   <int>12</int>
  </void>
  <void property="number2">
   <int>13</int>
  </void>
 </object>
</java>

โปรดทราบว่าการใช้java.beans.XMLDecoderข้อมูลที่ผู้ใช้ให้มาอาจทำให้เกิดช่องโหว่ในการใช้รหัสโดยอำเภอใจในรหัสของคุณ
aventurin

2

XMLBeansทำงานได้ดีถ้าคุณมีสคีมาสำหรับ XML ของคุณ สร้างวัตถุ Java สำหรับสคีมาและสร้างวิธีการแยกวิเคราะห์ที่ใช้งานง่าย


0

หากคุณกำลังพูดถึงการจัดลำดับวัตถุ XML โดยอัตโนมัติลองดูCastor :

Castor เป็นเฟรมเวิร์กการผูกข้อมูลโอเพ่นซอร์สสำหรับ Java [tm] เป็นเส้นทางที่สั้นที่สุดระหว่างวัตถุ Java เอกสาร XML และตารางเชิงสัมพันธ์ Castor จัดเตรียมการรวม Java-to-XML, การคงอยู่ของ Java-to-SQL และอื่น ๆ


0

โดยปกติแล้วฉันจะใช้jaxbหรือXMLBeansหากฉันต้องการสร้างอ็อบเจกต์ต่อเนื่องกับ XML ตอนนี้ฉันเห็นแล้วว่าXStreamอาจมีประโยชน์มากเพราะไม่เป็นการรบกวนและมี API ที่เรียบง่ายจริงๆ ฉันจะเล่นกับมันเร็ว ๆ นี้และอาจใช้มัน ข้อเสียเปรียบเพียงประการเดียวที่ฉันสังเกตเห็นคือฉันไม่สามารถสร้าง id ของวัตถุด้วยตัวเองสำหรับการอ้างอิงข้าม

@Barak Schiller
ขอบคุณสำหรับการโพสต์ลิงก์ไปยัง XStream!


ปัญหาคือ jaxb และ xmlbeans ต้องการสคีมาการแมปและไม่อัตโนมัติ ...
mP


0

หากคุณต้องการโซลูชันที่มีโครงสร้าง (เช่น ORM) JAXB2 เป็นทางออกที่ดี

หากคุณต้องการอนุกรมเช่น DOT NET คุณสามารถใช้Long Term Persistence ของ JavaBeans Components

ทางเลือกขึ้นอยู่กับการใช้การทำให้เป็นอนุกรม


-1
public static String genXmlTag(String tagName, String innerXml, String properties )
{
    return String.format("<%s %s>%s</%s>", tagName, properties, innerXml, tagName);
}

public static String genXmlTag(String tagName, String innerXml )
{
    return genXmlTag(tagName, innerXml, "");
}

public static <T> String serializeXML(List<T> list)
{
    String result = "";
    if (list.size() > 0)
    {
        T tmp = list.get(0);
        String clsName = tmp.getClass().getName();
        String[] splitCls = clsName.split("\\.");
        clsName = splitCls[splitCls.length - 1];
        Field[] fields = tmp.getClass().getFields();

        for (T t : list)
        {
            String row = "";
            try {
                for (Field f : fields)
                {
                    Object value = f.get(t);
                    row += genXmlTag(f.getName(), value == null ? "" : value.toString());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            row = genXmlTag(clsName, row);

            result += row;
        }
    }

    result = genXmlTag("root", result);
    return result;
}

ปัญหามากมาย: การสร้างใหม่ของคลาส # getSimpleName *** การประดิษฐ์ใหม่ของ PropertyDescriptor *** ถือว่าคุณสมบัติทั้งหมดเป็นฟิลด์ที่สามารถเข้าถึงได้ *** ไม่แคชผลการสะท้อน (สโลว์) *** ไม่มีวิธีปรับแต่งอะไรเลย (เช่นฉันต้องเปลี่ยน ชื่อคลาสและไฟล์) *** No deserialization
toolforger
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.