簡體   English   中英

jaxb-多對多關系

[英]jaxb - many to many relationship

編輯:

我現在有些混亂了,得出以下XML結果:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<List>
    <client name="Robert">
        <fileNames name="anleitung.pdf"/>
        <fileNames name="fernseher.jpg"/>
        <fileNames name="pikantesfoto.jpg"/>
    </client>
    <client name="Jakob">
        <fileNames name="fernseher.jpg"/>
        <fileNames name="pikantesfoto.jpg"/>
        <fileNames name="tagebuch.txt"/>
    </client>
</List>

這並不是真正的多對多關系,但是很接近,我需要刪除數據冗余。

“文件名”應為單個元素,客戶端應在其上指出。 因此,如果一個文件與其他客戶端的文件具有相同的名稱,則該文件應僅出現一次。

這是我的課程:

馬歇爾:公共類XMLMarshaller {

private Pool pool;

public XMLMarshaller(Pool pool) {
    this.pool = pool;
}

public void marshal() {

    JAXBContext jc;
    try {
        jc = JAXBContext.newInstance(Pool.class, Client.class, FileName.class);

        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Save XML-File");
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("XML-Document", "*.xml"));

        File path = fileChooser.showSaveDialog(new Stage());
        if (path.toString().endsWith(".xml") == false) {
            path = new File(path.toString() + ".xml");
        }
        if (path.isFile() == false)
            path.createNewFile();

        FileOutputStream fos = new FileOutputStream(path);
        OutputStreamWriter xmlOut = new OutputStreamWriter(fos, Charset.forName("UTF8"));

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        QName qName = new QName("List");
        JAXBElement<Pool> jaxbElement = new JAXBElement<>(qName, Pool.class, pool);
        marshaller.marshal(jaxbElement, xmlOut);

        xmlOut.flush();
        xmlOut.close();
    } catch (Exception e) {e.printStackTrace();}
}

}

池(包含所有現有“文件名”和客戶端的列表):

public class Pool {

private List<FileName> fileNames_pool;
private List<Client> clients;

public Pool() {
    this.fileNames_pool = new ArrayList<>(20);
    this.clients = new ArrayList<>(20);
}

public List<FileName> getFileNameList() {
    return this.fileNames_pool;
}

public List<FileName> getFileNames_pool() {
    return this.fileNames_pool;
}

@XmlAnyElement(lax = true)
public List<Client> getClientList() {
    return this.clients;
}


public boolean addClient(String clientName) {
    this.clients.add(new Client(clientName));
    return true;
}

public boolean addFileName(int clientIndex, String fileName) {

    int foundIndex = 0;
    boolean foundOne = false;

    for (int i=0; i<fileNames_pool.size(); ++i) {
        if (fileNames_pool.get(i).name == fileName) {
            foundIndex = i;
            foundOne = true;
            break;
        }
    }

    if (foundOne) {
        clients.get(clientIndex).addFileName(fileNames_pool.get(foundIndex));
    } else {
        FileName temp = new FileName(fileName);
        fileNames_pool.add(temp);
        clients.get(clientIndex).addFileName(temp);
    }
    return true;
}

}

客戶端(其中會有多個實例/對象): @XmlRootElement公共類客戶端{

static int numberOfClients = 0;

private int id;

@XmlAttribute
public String name;

public List<FileName> fileNames = new ArrayList<>();

public Client() {

}

public Client(String name) {
    this.name = name;
    this.id = numberOfClients++;
}

@XmlElement
public List<FileName> getFileNames() {
    return this.fileNames;
}

public void addFileName(FileName fileName) {
    this.fileNames.add(fileName);
}

}

文件名(還將有多個實例):

//@XmlRootElement
public class FileName {

//  public static int instanceCounter = 0;
//  
//  @XmlIDREF
//  public int idref = 0;

    @XmlAttribute
    public String name;

    public FileName() {

    }

    public FileName(String name) {
        this.name = name;
//      idref = instanceCounter++;
    }
}

您會看到有時我真的搞砸了,但是我完全不知道什么可行,什么無效。 如果我沒弄錯他的話,Pool課就像Blaise Doughan告訴我的包裝師一樣。 而我完全沒有得到的:為什么要基於字符串類創建一個“ id”?

這是一個如何使用jaxb將POJO映射到XML的示例http://www.mkyong.com/java/jaxb-hello-world-example/

但是,在您與您之間存在雙向關系的情況下, ClientName類具有對FileName類的引用,而FileName具有對ClientName的引用。 如果使用JAXB進行雙向XML映射,則需要在其中一種關系上使用@XmlTransient標記。 @XmlTransient可能不是您要查找的內容,因為無論注釋哪個字段,它將從該方向刪除。 使用afterUnmarshal方法可以解決此問題。 http://www.tutorialspoint.com/java/xml/javax_xml_bind_unmarshaller.listener_afterunmarshal.htm

或者,您可以使用MOXy的@XmlInverseReference來為您處理解組操作https://www.eclipse.org/eclipselink/documentation/2.4/moxy/shared_reference_relationships005.htm

JAXB要求

每個對象必須通過諸如容納/嵌套關系參考@XmlElement@XmlElementRef ,或@XmlAnyElement(lax=true)

非遏制關系

一旦有了由上述JAXB要求形成的樹,就可以使用@XmlID / @XmlIDREF形成文檔內關系(請參閱: http : @XmlIDREF xmlid-and.html )。 這是您在問題中作出以下陳述的地方:

以我的理解,如果我在兩個類中都保留兩個指向彼此的列表,但我在互聯網上讀到,應該涉及一個第三類,以將這兩個類以多對多的關系進行映射。

你能做什么?

看一下我給另一個問題的答案。 在該答案中,我演示了如何利用XmlAdapter通過包含來表示對象的首次出現,並通過引用來表示隨后的引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM