MOXy JAXB:如何将多个XML标记元素映射到相同的JAVA bean属性

时间:2012-03-21 15:20:07

标签: jaxb eclipselink moxy

我正在尝试使用MOXy JAXB解组XML文件。我有一组已经生成的类,我正在使用Xpath将我需要的每个XML元素映射到我的模型中。

我有一个像这样的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<fe:Facturae xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
    xmlns:fe="http://www.facturae.es/Facturae/2009/v3.2/Facturae">
    <Parties>
        <SellerParty>
            <LegalEntity>
                <CorporateName>Company Comp SA</CorporateName>
                <TradeName>Comp</TradeName>
                <ContactDetails>
                    <Telephone>917776665</Telephone>
                    <TeleFax>917776666</TeleFax>
                    <WebAddress>www.facturae.es</WebAddress>
                    <ElectronicMail>facturae@mityc.es</ElectronicMail>
                    <ContactPersons>Fernando</ContactPersons>
                    <CnoCnae>28000</CnoCnae>
                    <INETownCode>2134AAB</INETownCode>
                    <AdditionalContactDetails>Otros datos</AdditionalContactDetails>
                </ContactDetails>
            </LegalEntity>
        </SellerParty>
        <BuyerParty>
            <Individual>
                <Name>Juana</Name>
                <FirstSurname>Mauriño</FirstSurname>
                <OverseasAddress>
                    <Address>Juncal 1315</Address>
                    <PostCodeAndTown>00000 Buenos Aires</PostCodeAndTown>
                    <Province>Capital Federal</Province>
                    <CountryCode>ARG</CountryCode>
                </OverseasAddress>
                <ContactDetails>
                    <Telephone>00547775554</Telephone>
                    <TeleFax>00547775555</TeleFax>
                </ContactDetails>
            </Individual>
        </BuyerParty>
    </Parties>
</fe:Facturae>

然后我有我的模特:

@XmlRootElement(namespace="http://www.facturae.es/Facturae/2009/v3.2/Facturae", name="Facturae")
public class Facturae implements BaseObject, SecuredObject, CreationDataAware {
    @XmlPath("Parties/SellerParty")
    private Party sellerParty;

    @XmlPath("Parties/BuyerParty")
    private Party buyerParty;
}

public class Party implements BaseObject, SecuredObject, CreationDataAware {
@XmlPath("LegalEntity/ContactDetails")
    private ContactDetails contactDetails;
}

如您所见,<ContactDetails></ContactDetails><SellerParty></SellerParty>中存在<BuyerParty></BuyerParty>,但这两个标记共享相同的JAVA对象(Party)。使用上一个映射(@XmlPath(“LegalEntity / ContactDetails”)),我可以在SellerParty中正确传递ContactDetails信息,但我也希望同时传递<BuyerParty>中的ContactDetails。

我正在尝试这样的事情:

@XmlPaths(value = { @XmlPath("LegalEntity/ContactDetails"),@XmlPath("Individual/ContactDetails") })
    private ContactDetails contactDetails;

但它不起作用。

你们能帮我一把吗?

非常感谢。

1 个答案:

答案 0 :(得分:0)

您可以在此用例中使用XmlAdapter

<强> PartyAdapter

我们将使用XmlAdapterParty的实例转换为另一种类型的对象AdaptedPartyAdaptedParty将具有与Party中的每个属性相对应的两个属性(每个映射可能性一个)。我们将利用预初始化XmlAdapter实例的功能,在其上设置Facturae的实例。我们将使用Facturae的实例来确定我们正在处理的Party实例是sellerParty还是buyerParty

package forum9807536;

import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;

public class PartyAdapter extends XmlAdapter<PartyAdapter.AdaptedParty, Party> {

    private Facturae facturae;

    public PartyAdapter() {
    }

    public PartyAdapter(Facturae facturae) {
        this.facturae = facturae;
    }

    @Override
    public Party unmarshal(AdaptedParty v) throws Exception {
        Party party = new Party();
        if(v.individualName != null) {
            party.setName(v.individualName);
            party.setContactDetails(v.individualContactDetails);
        } else {
            party.setName(v.sellPartyName);
            party.setContactDetails(v.sellerPartyContactDetails);
        }
        return party;
    }

    @Override
    public AdaptedParty marshal(Party v) throws Exception {
        AdaptedParty adaptedParty = new AdaptedParty();
        if(null == facturae || facturae.getSellerParty() == v) {
            adaptedParty.sellPartyName = v.getName();
            adaptedParty.sellerPartyContactDetails = v.getContactDetails();
        } else {
            adaptedParty.individualName = v.getName();
            adaptedParty.individualContactDetails = v.getContactDetails();
        }
        return adaptedParty;
    }

    public static class AdaptedParty {

        @XmlPath("Individual/Name/text()")
        public String individualName;
        @XmlPath("Individual/ContactDetails")
        public ContactDetails individualContactDetails;

        @XmlPath("LegalEntity/CorporateName/text()")
        public String sellPartyName;
        @XmlPath("LegalEntity/ContactDetails")
        public ContactDetails sellerPartyContactDetails;
    }

}

<强>方

我们将使用@XmlJavaTypeAdapterPartyAdapterParty类相关联:

package forum9807536;

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

@XmlJavaTypeAdapter(PartyAdapter.class)
public class Party implements BaseObject, SecuredObject, CreationDataAware {
    private String name;
    private ContactDetails contactDetails;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ContactDetails getContactDetails() {
        return contactDetails;
    }

    public void setContactDetails(ContactDetails contactDetails) {
        this.contactDetails = contactDetails;
    }

}

<强>演示

以下演示代码演示了如何在XmlAdapter上设置预先初始化的Marshaller

package forum9807536;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

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

        File xml = new File("src/forum9807536/input.xml");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Facturae facturae = (Facturae) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setAdapter(new PartyAdapter(facturae));
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(facturae, System.out);
    }

}

<强>输出

以下是演示代码的输出,该代码对应于我已映射的模型部分。

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Facturae xmlns:ns0="http://www.facturae.es/Facturae/2009/v3.2/Facturae">
   <Parties>
      <BuyerParty>
         <Individual>
            <Name>Juana</Name>
            <ContactDetails/>
         </Individual>
      </BuyerParty>
      <SellerParty>
         <LegalEntity>
            <CorporateName>Company Comp SA</CorporateName>
            <ContactDetails/>
         </LegalEntity>
      </SellerParty>
   </Parties>
</ns0:Facturae>

了解更多信息