使用JAXB注释将XML文档解组为Oracle对象类型

时间:2013-09-13 05:40:27

标签: jaxb unmarshalling

我正在尝试将XML文档解组为Oracle SQL对象类型。

以下是XML示例:

<?xml version="1.0" encoding="UTF-8"?>
<order>
    <ordernumber>123-01</ordernumber>
    <customername>Idea Networks</customername>
    <item>
        <itemnumber>T-01</itemnumber>
        <quantity>1</quantity>
        <amount>10</amount>
    </item>
    <item>
        <itemnumber>T-20</itemnumber>
        <quantity>3</quantity>
        <amount>8</amount>
    </item>
</order>

以下是oracle数据库中oracle对象类型的定义:

CREATE OR REPLACE TYPE Item AS OBJECT
(
     ItemNumber               VARCHAR2(240)
    ,Quantity                 NUMBER     
    ,Amount                   NUMBER
); 

CREATE OR REPLACE TYPE ItemsArray IS TABLE OF Item;

CREATE OR REPLACE TYPE ItemOrder AS OBJECT
(
     OrderNumber               VARCHAR2(240)
    ,CustomerName              VARCHAR2(240)     
    ,Items                     ItemsArray
); 

现在我使用Jpublisher为对象生成java类

java oracle.jpub.Doit -user=scott/tiger -sql=ItemOrder -package=xxcmpon.order.test

我已经生成了5个类(Item.java,ItemRef.java,ItemOrder.java,ItemOrderRef.java,Itemsarray.java)

ItemOrder类如下所示:

package xxcmpon.order.test;

import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.STRUCT;
import oracle.jpub.runtime.MutableStruct;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name="order")
@XmlType(name = "ItemOrder", propOrder = {
    "ordernumber",
    "customername",
    "items" 
})
public class ItemOrder implements ORAData, ORADataFactory
{
  public static final String _SQL_NAME = "SCOTT.ITEMORDER";
  public static final int _SQL_TYPECODE = OracleTypes.STRUCT;

  protected MutableStruct _struct;

  protected static int[] _sqlType =  { 12,12,2003 };
  protected static ORADataFactory[] _factory = new ORADataFactory[3];
  static
  {
    _factory[2] = Itemsarray.getORADataFactory();
  }
  protected static final ItemOrder _ItemOrderFactory = new ItemOrder();

  public static ORADataFactory getORADataFactory()
  { return _ItemOrderFactory; }
  /* constructors */
  protected void _init_struct(boolean init)
  { if (init) _struct = new MutableStruct(new Object[3], _sqlType, _factory); }
  public ItemOrder()
  { _init_struct(true); }
  public ItemOrder(String ordernumber, String customername, Itemsarray items) throws SQLException
  { _init_struct(true);
    setOrdernumber(ordernumber);
    setCustomername(customername);
    setItems(items);
  }

  /* ORAData interface */
  public Datum toDatum(Connection c) throws SQLException
  {
    return _struct.toDatum(c, _SQL_NAME);
  }


  /* ORADataFactory interface */
  public ORAData create(Datum d, int sqlType) throws SQLException
  { return create(null, d, sqlType); }
  protected ORAData create(ItemOrder o, Datum d, int sqlType) throws SQLException
  {
    if (d == null) return null; 
    if (o == null) o = new ItemOrder();
    o._struct = new MutableStruct((STRUCT) d, _sqlType, _factory);
    return o;
  }
  /* accessor methods */
  public String getOrdernumber() throws SQLException
  { return (String) _struct.getAttribute(0); }

  public void setOrdernumber(String ordernumber) throws SQLException
  { _struct.setAttribute(0, ordernumber); }


  public String getCustomername() throws SQLException
  { return (String) _struct.getAttribute(1); }

  public void setCustomername(String customername) throws SQLException
  { _struct.setAttribute(1, customername); }


  public Itemsarray getItems() throws SQLException
  { return (Itemsarray) _struct.getAttribute(2); }

  public void setItems(Itemsarray items) throws SQLException
  { _struct.setAttribute(2, items); }

}

Item类如下所示:

package xxcmpon.order.test;

import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.STRUCT;
import oracle.jpub.runtime.MutableStruct;

import javax.xml.bind.annotation.XmlType;

@XmlType(name = "Item", propOrder = {
    "itemnumber",
    "quantity",
    "amount"    
})
public class Item implements ORAData, ORADataFactory
{
  public static final String _SQL_NAME = "SCOTT.ITEM";
  public static final int _SQL_TYPECODE = OracleTypes.STRUCT;

  protected MutableStruct _struct;

  protected static int[] _sqlType =  { 12,2,2 };
  protected static ORADataFactory[] _factory = new ORADataFactory[3];
  protected static final Item _ItemFactory = new Item();

  public static ORADataFactory getORADataFactory()
  { return _ItemFactory; }
  /* constructors */
  protected void _init_struct(boolean init)
  { if (init) _struct = new MutableStruct(new Object[3], _sqlType, _factory); }
  public Item()
  { _init_struct(true); }
  public Item(String itemnumber, java.math.BigDecimal quantity, java.math.BigDecimal amount) throws SQLException
  { _init_struct(true);
    setItemnumber(itemnumber);
    setQuantity(quantity);
    setAmount(amount);
  }

  /* ORAData interface */
  public Datum toDatum(Connection c) throws SQLException
  {
    return _struct.toDatum(c, _SQL_NAME);
  }


  /* ORADataFactory interface */
  public ORAData create(Datum d, int sqlType) throws SQLException
  { return create(null, d, sqlType); }
  protected ORAData create(Item o, Datum d, int sqlType) throws SQLException
  {
    if (d == null) return null; 
    if (o == null) o = new Item();
    o._struct = new MutableStruct((STRUCT) d, _sqlType, _factory);
    return o;
  }
  /* accessor methods */
  public String getItemnumber() throws SQLException
  { return (String) _struct.getAttribute(0); }

  public void setItemnumber(String itemnumber) throws SQLException
  { _struct.setAttribute(0, itemnumber); }


  public java.math.BigDecimal getQuantity() throws SQLException
  { return (java.math.BigDecimal) _struct.getAttribute(1); }

  public void setQuantity(java.math.BigDecimal quantity) throws SQLException
  { _struct.setAttribute(1, quantity); }


  public java.math.BigDecimal getAmount() throws SQLException
  { return (java.math.BigDecimal) _struct.getAttribute(2); }

  public void setAmount(java.math.BigDecimal amount) throws SQLException
  { _struct.setAttribute(2, amount); }

}

Itemsarray类如下所示:

package xxcmpon.order.test;

import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.jpub.runtime.MutableArray;

import javax.xml.bind.annotation.XmlElement;

public class Itemsarray implements ORAData, ORADataFactory
{
  public static final String _SQL_NAME = "SCOTT.ITEMSARRAY";
  public static final int _SQL_TYPECODE = OracleTypes.ARRAY;

  MutableArray _array;


private static final Itemsarray _ItemsarrayFactory = new Itemsarray();

  public static ORADataFactory getORADataFactory()
  { return _ItemsarrayFactory; }
  /* constructors */
  public Itemsarray()
  {
    this((Item[])null);
  }

  public Itemsarray(Item[] a)
  {
    _array = new MutableArray(2002, a, Item.getORADataFactory());
  }

  /* ORAData interface */
  public Datum toDatum(Connection c) throws SQLException
  {
    return _array.toDatum(c, _SQL_NAME);
  }

  /* ORADataFactory interface */
  public ORAData create(Datum d, int sqlType) throws SQLException
  {
    if (d == null) return null; 
    Itemsarray a = new Itemsarray();
    a._array = new MutableArray(2002, (ARRAY) d, Item.getORADataFactory());
    return a;
  }

  public int length() throws SQLException
  {
    return _array.length();
  }

  public int getBaseType() throws SQLException
  {
    return _array.getBaseType();
  }

  public String getBaseTypeName() throws SQLException
  {
    return _array.getBaseTypeName();
  }

  public ArrayDescriptor getDescriptor() throws SQLException
  {
    return _array.getDescriptor();
  }

  /* array accessor methods */
  public Item[] getArray() throws SQLException
  {
    return (Item[]) _array.getObjectArray(
      new Item[_array.length()]);
  }

  public Item[] getArray(long index, int count) throws SQLException
  {
    return (Item[]) _array.getObjectArray(index,
      new Item[_array.sliceLength(index, count)]);
  }

  public void setArray(Item[] a) throws SQLException
  {
    _array.setObjectArray(a);
  }

  public void setArray(Item[] a, long index) throws SQLException
  {
    _array.setObjectArray(a, index);
  }

  public Item getElement(long index) throws SQLException
  {
    return (Item) _array.getObjectElement(index);
  }

  public void setElement(Item a, long index) throws SQLException
  {
    _array.setObjectElement(a, index);
  }

}

对于上面的类,我添加了JAXB注释来读取XML文档。

我正在尝试解组xml文档并通过示例脚本打印它,如下所示:

public class Main {
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(ItemOrder.class);
        Unmarshaller u = jc.createUnmarshaller();
        Marshaller m = jc.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        try {
            ItemOrder orderx = (ItemOrder)u.unmarshal(new FileInputStream("order.xml"));
            Itemsarray  items = orderx.getItems();          
            System.out.println("Order Number : " + orderx.getOrdernumber());
            //Item[] itemo = items.getArray();
            //System.out.println("Item Number : " + itemo[0].getItemnumber());

            m.marshal(orderx, System.out);
        } catch(javax.xml.bind.UnmarshalException e){
            System.out.println("Main: " + e);
        } catch(Exception e1){  
            System.out.println("Main: " + e1);
            e1.printStackTrace();
        }       
    }
}

[ttr12@rstnssiovm0015 test]$ java xxcmpon.order.test.Main
Order Number : 123-01
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<order>
    <ordernumber>123-01</ordernumber>
    <customername>Idea Networks</customername>
</order>
[ttr12@rstnssiovm0015 test]$

我希望输出显示如下所示的项目:

<?xml version="1.0" encoding="UTF-8"?>
<order>
    <ordernumber>123-01</ordernumber>
    <customername>Idea Networks</customername>
    <item>
        <itemnumber>T-01</itemnumber>
        <quantity>1</quantity>
        <amount>10</amount>
    </item>
    <item>
        <itemnumber>T-20</itemnumber>
        <quantity>3</quantity>
        <amount>8</amount>
    </item>
</order>

我想我缺少一些注释来绑定items数组,这是我无法弄清楚的。 有人可以让我知道我缺少的注释是什么以及在哪里添加?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我建议你以编程方式准备ItemOrder对象中的几个Item,然后将其编组到标准输出中。封送的XML明显不同于您手动创建的XML。它会给你一个想法,你原来的XML有什么问题。 您可能会毫不费力地将该XML解组回Java级。