2

我正在使用EclipseLink MOXy作为我的JAXB (JSR-222)提供程序,并且需要一些关于我的映射文件的帮助来将我的类编组为 XML。

我正在使用外部文件进行映射。

我有两种类型的交易:A 和 B。两者都包含一个带有两个字段(text1 和 text2)的标题对象(相同的对象)。

在将这些编组为 XML 时,我希望 transactionA 的标头字段的 xml 标记成为 <headerA1> 和 <headerA2>,并且链接到 transactionB 的那些成为 <headerB1> 和 <headerB2>。

知道如何实现这一点(最好不使用继承)?

这是代码:

标题类

public class Header {

    private String text1;
    private String text2;

      public Header(){}

    public String getText1() {
        return text1;
    }

    public void setText1(String text1) {
        this.text1 = text1;
    }

    public String getText2() {
        return text2;
    }

    public void setText2(String text2) {
        this.text2 = text2;
    }

}

交易一

public class TransactionA {

    private Header statementHeader;
    private BigDecimal units;
    private BigDecimal price;

    public TransactionA(){}

    public BigDecimal getUnits() {
        return units;
    }

    public void setUnits(BigDecimal units) {
        this.units = units;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Header getStatementHeader() {
        return statementHeader;
    }

    public void setStatementHeader(Header statementHeader) {
        this.statementHeader = statementHeader;
    }

}

交易乙

public class TransactionB {

  private Header statementHeader;
    private BigDecimal units;
    private BigDecimal price;

    public TransactionB(){}

    public BigDecimal getUnits() {
        return units;
    }

    public void setUnits(BigDecimal units) {
        this.units = units;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Header getStatementHeader() {
        return statementHeader;
    }

    public void setStatementHeader(Header statementHeader) {
        this.statementHeader = statementHeader;
    }

}

映射文件

<java-types>
  <java-type name="Statement" xml-accessor-type="NONE">
     <java-attributes>
        <xml-element java-attribute="tranA" />
        <xml-element java-attribute="tranB" />
     </java-attributes>
  </java-type>
  <java-type name="Header" xml-accessor-type="NONE">
     <java-attributes>
        <xml-element java-attribute="text1" name="headerA1" />
        <xml-element java-attribute="text2" name="headerA2" />
     </java-attributes>
  </java-type>
  <java-type name="TransactionA" xml-accessor-type="NONE">
     <java-attributes>
        <xml-element java-attribute="statementHeader" name="headerA" />
        <xml-element java-attribute="units" />
        <xml-element java-attribute="price"/>
     </java-attributes>
  </java-type>
  <java-type name="TransactionB" xml-accessor-type="NONE">
     <java-attributes>
        <xml-element java-attribute="statementHeader" name="headerB" />
        <xml-element java-attribute="units" />
        <xml-element java-attribute="price"/>
     </java-attributes>
  </java-type>
</java-types>

结果如您所见,标题 B 的标签与标题 A 的标签相同。

<?xml version="1.0" encoding="UTF-8"?>
<tranA>
   <headerA>
      <headerA1>Description</headerA1>
      <headerA2>Units</headerA2>
   </headerA>
   <units>10</units>
   <price>99999999.98999999463558197021484375</price>
</tranA><tranB>
   <headerB>
      <headerA1>Bheader1</headerA1>
      <headerA2>Bheader2</headerA2>
   </headerB>
   <units>10</units>
   <price>99999999.98999999463558197021484375</price>
</tranB>
4

1 回答 1

0

一段时间以来,我们已经针对此类行为提出了增强请求。如果您可以对以下内容进行投票,但这将有助于将其提升到我们的优先级列表中。


您今天如何做到这一点

XmlAdapter (HeaderBAdapter)

您可以使用 anXmlAdapterHeader该类提供备用映射。

package forum13986357;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class HeaderBAdapter extends XmlAdapter<HeaderBAdapter.AdaptedHeaderB, Header>{

    public static class AdaptedHeaderB {
        public String headerB1;
        public String headerB2;
    }

    @Override
    public AdaptedHeaderB marshal(Header header) throws Exception {
        AdaptedHeaderB adaptedHeaderB = new AdaptedHeaderB();
        adaptedHeaderB.headerB1 = header.getText1();
        adaptedHeaderB.headerB2 = header.getText2();
        return adaptedHeaderB;
    }

    @Override
    public Header unmarshal(AdaptedHeaderB adaptedHeaderB) throws Exception {
        Header header = new Header();
        header.setText1(adaptedHeaderB.headerB1);
        header.setText2(adaptedHeaderB.headerB2);
        return header;
    }

}

oxm.xml

以下是映射文档的更新版本。我已经更新了类中statementHeader属性的映射TransactionB以指定XmlAdapter应该使用 。

<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum13986357">
    <java-types>
        <java-type name="Statement" xml-accessor-type="NONE">
            <java-attributes>
                <xml-element java-attribute="tranA" />
                <xml-element java-attribute="tranB" />
            </java-attributes>
        </java-type>
        <java-type name="Header" xml-accessor-type="NONE">
            <java-attributes>
                <xml-element java-attribute="text1" name="headerA1" />
                <xml-element java-attribute="text2" name="headerA2" />
            </java-attributes>
        </java-type>
        <java-type name="TransactionA" xml-accessor-type="NONE">
            <java-attributes>
                <xml-element java-attribute="statementHeader" name="headerA" />
                <xml-element java-attribute="units" />
                <xml-element java-attribute="price" />
            </java-attributes>
        </java-type>
        <java-type name="TransactionB" xml-accessor-type="NONE">
            <java-attributes>
                <xml-element java-attribute="statementHeader" name="headerB">
                    <xml-java-type-adapter value="forum13986357.HeaderBAdapter" />
                </xml-element>
                <xml-element java-attribute="units" />
                <xml-element java-attribute="price" />
            </java-attributes>
        </java-type>
    </java-type

s>

jaxb.properties

要将 MOXy 用作您的 JAXB 提供程序,您需要包含一个jaxb.properties在与域模型相同的包中调用的文件,其中包含以下条目 (http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your .html):

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

演示

下面的演示代码可以用来证明一切正常。

package forum13986357;

import java.util.*;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum13986357/oxm.xml");
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Statement.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource xml = new StreamSource("src/forum13986357/input.xml");
        JAXBElement<Statement> jaxbElement = unmarshaller.unmarshal(xml, Statement.class);

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

}

输入.xml/输出

<?xml version="1.0" encoding="UTF-8"?>
<statement>
    <tranA>
        <headerA>
            <headerA1>Description</headerA1>
            <headerA2>Units</headerA2>
        </headerA>
        <units>10</units>
        <price>99999999.98999999463558197021484375</price>
    </tranA>
    <tranB>
        <headerB>
            <headerB1>Bheader1</headerB1>
            <headerB2>Bheader2</headerB2>
        </headerB>
        <units>10</units>
        <price>99999999.98999999463558197021484375</price>
    </tranB>

于 2012-12-21T16:19:17.100 回答