2012-03-21 2 views
1

Я пытаюсь размонтировать XML-файл с помощью MOXy JAXB. У меня есть набор классов, уже сгенерированный, и я использую Xpath для сопоставления каждого элемента XML, который мне нужен, в мою модель.MOXy JAXB: как сопоставить несколько элементов XML-тегов с тем же свойством JAVA-компонента

У меня есть файл 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>[email protected]</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»)) Я могу правильно передать информацию ContactDetails в SalesParty, но хочу также передать ContactDetails в <BuyerParty> одновременно.

Я пытался что-то вроде этого:

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

, но он не работает.

Можете ли вы, ребята, дать мне руку?

спасибо.

ответ

0

Вы можете использовать XmlAdapter для этого случая использования:

PartyAdapter

Мы будем использовать XmlAdapter для преобразования экземпляра Party к другому типу объекта AdaptedParty. AdaptedParty будет иметь два свойства, соответствующие каждому свойству в 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; 
    } 

} 

партия

Мы будем использовать @XmlJavaTypeAdapter связать PartyAdapter к Party класса:

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> 

Для получения более подробной информации

+1

Спасибо большое, это прекрасно! – rocotocloc

Смежные вопросы