2012-07-05 44 views
5

現狀從Java生成XML文檔對象,其中結構有很大的不同

我在Java中的複雜模型對象圖需要被翻譯來回轉換爲XML文檔。 XML文檔模式的對象圖結構與模型的對象樹極其不同。這兩者是可以互換的,但翻譯需要大量使用父母/子女關係的情境驅動邏輯。

的問題

我與已經很好地建立在舊系統和XML文檔的架構是相當新的模型對象的工作。由於我們的許多代碼依賴於模型對象的結構,我們不想重構它們。下面是結構上的差異我處理的類型的一個簡化的例子:

實施例的數據模型樹

項目

  • 說明
  • 成本
  • .. 。

  • 地址
  • ...

地址

  • ...

SaleTransaction(*這是被翻譯的東西)

  • 買家(人)
  • 賣家(人)
  • 已售項目[](列表)
  • 交換的項目[] (列表)
  • 交易地點(地址)

實施例的XML文檔結構

交換

  • 類型
  • 締約方
    • party_contact_ref
      • 類型
      • CONTACT_ID
  • 交易詳情
    • total_amount_exchanged
  • 項目
    • 項目
      • owning_party_contact_ref_id
      • exchange_use_type
  • 聯繫
    • 聯繫
      • ID

兌換類型:[現金出售| BARTER |組合現金和巴特爾]

聯繫類型:[PERSON | ADDRESS]

更改詳情類型:[現金交易| BARTER EXCHANGE]

SaleTransaction和Exchange之間的映射是可能的,只是不是1-1。在該示例中,模型中的「買家」將被映射到XML文檔中的聯繫人和聯繫人引用元素。此外,「Item」元素的「owning_party_contact_ref_id」屬性的值將通過查看SaleTransaction對象圖中的幾個不同值來確定。

如果我正在使用的對象圖需要一些翻譯以便在XML文檔中使用,那麼我的轉向工具是一個XmlAdapter。但在這種情況下,我沒有看到使用JAXB XML適配器作爲可行的解決方案,原因有三。

  1. 模型圖中對象中的哪個XML元素也與數據相關。我相信所有的XmlAdapter類/屬性映射都是固定的。
  2. 似乎無法與XmlAdapters進行多對一或多對一的解決方案。 MOXy有一個interesting extension,但同樣需要固定映射到屬性。
  3. 據我所知,XmlAdapters可以處理單個對象,並且沒有辦法獲取整編/解組圖的整個圖的上下文。

問題

我敢肯定,這類型的問題是相當普遍的,所以你怎麼處理呢?有沒有辦法用標準工具來處理這個問題?

我想出

在情況下,它很有趣,這裏是我想出來的各種可能的方法:

#1 獨立對象圖轉換問題來自XML生成問題。我有一個本土工具,可以幫助您根據某些上下文對象生成對象圖。我可以從XML模式創建JAXB類,然後依靠此工具根據模型對象的上下文生成這些類的對象。這可以很好地從模型對象圖生成一個XML文檔,但不是相反。這也意味着依賴非標準工具,如果可能的話,我想盡量避免使用這些工具。

#2 轉到XmlAdapter瘋狂和修改模型類能夠保留轉換狀態的信息(例如使用該對象模型樹創建XML文檔中該元素)。這將使問題與JAXB的標準使用模型非常接近,但我認爲這將是開發,測試和維護的噩夢。

#3 像我在#1中分開對象圖問題,但使用JDOM而不是JAXB。這將刪除所有JAXB所需的類和映射,但需要構建另一個定製工具來管理模型對象到DOM樹的映射。

我對這三種解決方案中的任何一種都不感興趣,但我最偏愛#1。

+0

您可能對EclipseLink JAXB(MOXy)中的「@ XmlPath」擴展感興趣。以下是對象模型與XML文檔完全不同的示例:http://blog.bdoughan.com/2010/09/xpath-based-mapping-geocode-example.html。 – 2012-07-05 19:32:55

+0

我看過'@ XmlPath'擴展名,但我不確定如何管理數據驅動的條件映射。例如,如果一個java對象的屬性可以映射到XML文檔中N個可能位置的子集,取決於數據,那麼將如何使用'@ XmlPath'擴展來完成?對不起,如果我錯過了明顯的東西! – Terence 2012-07-05 20:03:08

+0

當對象模型與XML不同時,「@ XmlPath」擴展是有用的。如果您的主要關注點是現在擁有一個'XmlAdapter',那麼您可能更喜歡使用有狀態的'XmlAdapter':http://blog.bdoughan.com/2011/09/mixing-nesting-and-references-with。 html – 2012-07-05 20:09:55

回答

2

1是你最好的選擇恕我直言。編寫映射代碼很乏味,但你應該抵制太聰明的衝動。您使用的任何映射工具都需要配置,我敢打賭,這與手動編寫Java映射代碼一樣有效。只需編寫大量的單元測試。

您可以嘗試使用任何具有類似命名字段的類的Dozer,它將使用反射來執行映射。我過去使用過這個,但是我的模式看起來更像我的域對象,所以它可能不是那麼有用。

爲了讓代碼更愉快,使用所有可以爲JAXB找到的xjc插件,比如流利api和值構造函數。

+0

我有點害怕,會得到答案。我會抱抱一些我從來沒有聽說過的令人敬畏的工具或模式的希望。如果有人不進來,我會選擇你的答案。 – Terence 2012-07-06 00:20:50

0

對不起,我沒有給你一個直接的答案,但我還不能評論我的名譽,所以這裏是我的「答案」。

我肯定會嘗試Altova XML Spy它是Code Generation features。我已經嘗試過並且非常有用。我不知道它能做的是另一種方式,但由於它也有Database connectivity和其他一些東西,我相信它不會有任何傷害嘗試和玩弄它。

他們也有另一個應用程序叫做MapForce(如在映射數據庫中,而不是GIS),我從來沒有嘗試過,但是從他們中我會期望它非常有用。

我希望你能找到所有這些非常有用的東西,並且你可以對它進行評論,並提供更多關於它是如何幫助你(或不)的細節。

+0

我沒有看到XML Spy是如何改進這個問題的工具,但MapForce是一個有趣的方向。我正在尋找更多的設計模式或Java標準工具。購買一些專有軟件,讓它與我們的代碼庫一起工作,並學習如何使用它不會是我的第一選擇。如果沒有代碼驅動的解決方案,MapForce看起來像是一個非常好的產品。 – Terence 2012-07-05 19:55:38

+0

對不起,我無法爲更廣泛的答案做更多的研究,但是我儘管分享Altova產品可以幫助某種方式。我使用XML Spy中的代碼生成功能來生成從XSD到Java以及C#的類,並且它非常好用。我不知道,但我認爲他們可能有類似於從Java對象到XSD的一些東西,可以給你一些你正在尋找的東西。 – hectorg87 2012-07-05 20:00:22

+0

我很欣賞輸入!否則我將永遠不會了解MapForce,這可能會成爲我們走下坡路的方向。 – Terence 2012-07-05 20:04:29

0

如果您有xsd模式,使用像castor這樣的工具生成pojos非常有用。一旦你使用生成的pojos打包,你可以使用dozer來將你的「舊」對象模型映射到代表xml文檔的pojos。然後你只需使用的Marshaller到流變換蓖麻油生成的對象,字符串等

+0

在一個更簡單的情況下,這將工作完美。推土機使用反射做1-1映射,我的用例明確需要多對一的映射。這是[dozer不支持](http://dozer.sourceforge.net/documentation/faq.html#mult-fields-to-single-field) – Terence 2012-07-06 00:34:52

1

如果一個對象樹我與工作需要一些轉換,以 一個XML文檔中使用,我去到的工具是一個XmlAdapter。在這個 的情況下,我沒有看到使用JAXB XML適配器作爲一個可行的解決方案。 據我所知,XmlAdapters使用單個對象,而不是 有一種方法來獲取編組/編組的 整個樹的上下文。

正常情況下,XmlAdapter是無狀態的,但你可以指定一個實例XmlAdapter上包含狀態Marshaller/Unmarshaller。這可能是你所需要的。

YourAdapter yourAdapter = new YourAdapter(); 
yourAdapter.setState(someState); 
marshaller.setAdapter(yourAdapter); 
unmarshaller.setAdapter(yourAdapter); 

你在Marshaller/Unmarshaller指定的實例將被用於其中的相應的類被配置:

@XmlJavaTypeAdpater(YourAdapter.class) 

更多信息

+0

能夠指定'XmlAdapter'的特定實例爲用於編組/解組非常酷,我不知道。不過,我仍然遇到了一些麻煩,看看如何處理問題的有條件的多對一部分。我扔在一起的例子有一個「Person」對象,需要在3個區域中部分表示,具體取決於數據值:'Parties/contact_ref','Contacts/Contact'和'Items/Item/owning_party_contact_ref'。這是翻譯的這個條件部分,它真的讓我遠離了'XmlAdapter'。也許我只是想念一些東西? – Terence 2012-07-06 00:18:03