2012-07-05 108 views
1

在從我的喜架構root.class的元素項和ohter對象是一個itemList中的一部分:JAXB可映射的XML元素

@XmlElementRef(name = "item", namespace = "xi", type = JAXBElement.class, required = false) 
//... 
protected List<Object> itemList; 

我在ObjectFactory.class已經從主架構的一些項目作爲JAXBElements這樣的:

@XmlElementDecl(namespace = "de-schema", name = "detailedInformation", substitutionHeadNamespace = "xi", substitutionHeadName = "item") 
public JAXBElement<numItemType> createDetailedInformation(numItemType num) { 
    return new JAXBElement<numItemType>(_detailedInformation_QNAME, numItemType.class, null, num); 
} 

所以numItemType先後爲JAXBElement一些屬性和價值(NUM)。

NumItemType.class:

@XmlJavaTypeAdapter(numItemTypeAdapter.class) 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "numItemType", namespace = "xi", propOrder = { 
    "num" 
}) 

public class NumItemType { 

    @XmlValue 
    protected BigDecimal num; 
    @XmlAttribute(name = "precision") 
    protected String precision; 
    @XmlAttribute(name = "decimals") 
    protected String decimals; 
    //... more Attributes 

} 

但當JAXB解組的XML文件,它會只有要素,例如:

<detailedInformation> 
    <element1>1234</element1> 
    <element2>5678</element2> 
    <element3>bla</element3> 
</detailedInformation> 

當我名帥,它應該成爲(像JAXB java代碼):

<detailedInformation element2="5678" element3="bla">1234</detailedInformation> 

因此,我寫了numItemTypeAdapter.class與 NumItemTypeAdapter延伸XmlAdapter

AdaptedNum.class:

public class AdaptedNum { 
    @XmlElement 
    private double element1; 
    @XmlElement 
    private String element2; 
    @XmlElement 
    private String element3; 

    /** Some getter/setter methods */ 
} 

我想,這將是幫助我http://blog.bdoughan.com/2012/02/xmlanyelement-and-xmladapter.html,但它畢竟是一個有點棘手: -/

回答

0

找出你的問題可能發生的位置有點棘手。我假設您的原始模型是從XML模式生成的,這應該沒有任何修改就能正常工作。我在下面試圖提供一個縮小版本的例子,這可能會有所幫助。

package forum11343610; 

import java.util.*; 
import javax.xml.bind.JAXBElement; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 

    @XmlElementRef(name = "item", namespace = "xi", type = JAXBElement.class, required = false) 
    protected List<Object> itemList = new ArrayList<Object>(); 

    public List<Object> getItemList() { 
     return itemList; 
    } 

    public void setItemList(List<Object> itemList) { 
     this.itemList = itemList; 
    } 

} 

NumItemType

package forum11343610; 

import java.math.BigDecimal; 
import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "numItemType", namespace = "xi", propOrder = { 
    "num" 
}) 

public class NumItemType { 

    @XmlValue 
    protected BigDecimal num; 
    @XmlAttribute(name = "precision") 
    protected String precision; 
    @XmlAttribute(name = "decimals") 
    protected String decimals; 
    //... more Attributes 

} 

的ObjectFactory

package forum11343610; 

import javax.xml.bind.JAXBElement; 
import javax.xml.bind.annotation.*; 
import javax.xml.namespace.QName; 

@XmlRegistry 
public class ObjectFactory { 

    private static final QName _detailedInformation_QNAME = new QName("de-schema", "detailedInformation"); 

    @XmlElementDecl(namespace = "xi", name = "item") 
    public JAXBElement<NumItemType> createItem(NumItemType num) { 
     return new JAXBElement<NumItemType>(_detailedInformation_QNAME, NumItemType.class, null, num); 
    } 

    @XmlElementDecl(namespace = "de-schema", name = "detailedInformation", substitutionHeadNamespace = "xi", substitutionHeadName = "item") 
    public JAXBElement<NumItemType> createDetailedInformation(NumItemType num) { 
     return new JAXBElement<NumItemType>(_detailedInformation_QNAME, NumItemType.class, null, num); 
    } 

} 

演示

package forum11343610; 

import java.math.BigDecimal; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Root.class, ObjectFactory.class); 

     ObjectFactory objectFactory = new ObjectFactory(); 
     Root root = new Root(); 

     NumItemType numItemType = new NumItemType(); 
     numItemType.num = BigDecimal.TEN; 
     numItemType.decimals = "1"; 
     numItemType.precision = "2"; 
     root.getItemList().add(objectFactory.createDetailedInformation(numItemType)); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(root, System.out); 
    } 

} 

輸出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root xmlns:ns2="de-schema" xmlns:ns3="xi"> 
    <ns2:detailedInformation precision="2" decimals="1">10</ns2:detailedInformation> 
</root> 
0

感謝您的評論。

這就是問題所在:

演示

NumItemType numItemType = new NumItemType(); 
numItemType.num = BigDecimal.TEN; 
numItemType.decimals = "1"; 
numItemType.precision = "2"; 
root.getItemList().add(objectFactory.createDetailedInformation(numItemType)); 

應該解組,並自動映射XML。

XML輸入

<detailedInformation> 
    <element1>1234</element1> 
    <element2>5678</element2> 
    <element3>bla</element3> 
</detailedInformation> 

與代碼:

演示

JAXBContext jc = JAXBContext.newInstance(Root.class, ObjectFactory.class); 
Unmarshaller u = jc.createUnmarshaller(); 
File xml = new File("D:/", "test.xml"); 
Root root = (Root) u.unmarshal(xml); 

輸出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root xmlns:ns2="de-schema" xmlns:ns3="xi"> 
    <ns2:detailedInformation precision="2" decimals="1">10</ns2:detailedInformation> 
</root> 

我可以用DOM將XML文檔解析爲樹並用JAXB進行編組...

謝謝!

0

換句話說:

我想設置新的元素到NumItemType.class的解組,而不改變架構的Java代碼。

NumItemType.class

package forum11343610; 

import java.math.BigDecimal; 
import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "numItemType", namespace = "xi", propOrder = { 
    "num" 
}) 

    @XmlJavaTypeAdapter(NumItemTypeAdapter.class) 
    public class NumItemType { 

     @XmlValue 
     protected BigDecimal num; 
     @XmlAttribute(name = "precision") 
     protected String precision; 
     @XmlAttribute(name = "decimals") 
     protected String decimals; 
     //... more Attributes 

    } 

NumItemTypeAdapter.class

public class NumItemTypeAdapter extends XmlAdapter<AdaptedNum, NumItemType> { 

    @Override 
    public NumItemType unmarshal(AdaptedNum an) throws Exception { 
     NumItemType nit = new NumItemType(); 
     nit.setNum(an.getNum); 
     nit.setPrecision(an.getPrecision); 
     nit.setDecimals(an.getDecimals) 
     return nit; 
    } 

} 

AdaptedNum.class

@XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "adaptedNum", namespace = "", propOrder = { 
     "element1", 
     "element2", 
     "element3" 
    }) 

    public class AdaptedNum { 

     @XmlElement(name ="element1") 
     protected BigDecimal num; 
     @XmlElement(name ="element2") 
      private String decimals; 
     @XmlElement(name ="element3") 
      private String precison; 
      // set/get method 
}