2011-05-22 26 views
1

我使用MOXy解組一個相對簡單的XML文檔,但我得到不一致的行爲。該文件由兩個元素組成,其中包含基本信息(名稱和日期),後跟一系列記錄。問題在於名稱和日期每次都正確解組,但是我經常沒有得到任何記錄(這已經通過使用相同的靜態數據傳遞和失敗而沒有觀察到的可預測性的單元測試進行驗證)。所有的日誌記錄和斷言都證明一切都很好,除了有時我得到所有6條記錄,有時我得到0(從來沒有任何其他數字)。這種不一致的行爲對我來說絕對沒有意義,有什麼想法?我是否缺少註釋或可確保正確解組的錯誤?與MOXy不一致的反編組

我已經嘗試了幾個不同版本的eclipselink庫,所有結果都相同(目前我正在從eclipselink maven資源庫中加載2.2.0)。

報告類

package com.company.report_parser.model; 

import org.eclipse.persistence.oxm.annotations.XmlPath; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import java.util.List; 

@XmlRootElement(name="feedback") 
public class SpecificAggregateReport extends AggregateReport { 
    @XmlPath("submitter/org_name/text()") 
    protected void setPartnerName(String partnerName) { 
     super.setPartnerName(partnerName); 
    } 

    @XmlPath("date_range/end/text()") 
    protected void setDate(String date) { 
     super.setDate(date); 
    } 

    public List<AggregateRecord> getRecords() { 
     return super.getRecords(); 
    } 
    @XmlPath("authstats/record") 
    @XmlElement(type=SpecificAggregateRecord.class) // This is the element class which implements the AggregateRecord Interface used in the List 
    protected void setRecords(List<AggregateRecord> records) { 
     super.setRecords(records); 
    } 
} 

記錄類 包com.company.report_parser.model;

import org.eclipse.persistence.oxm.annotations.XmlPath; 

public class SpecificAggregateRecord extends AggregateRecord { 
    @XmlPath("row/@source_ip") 
    protected void setSourceIp(String sourceIp) { 
     super.setSourceIp(sourceIp); 
    } 

    @XmlPath("row/@count") 
    protected void setCount(String count) { 
     super.setCount(count); 
    } 

    @XmlPath("identities/@envelope_from") 
    protected void setSmtpFrom(String envelope_from) { 
     super.setSmtpFrom(envelope_from); 
    } 

    @XmlPath("identities/@header_from") 
    protected void setHeaderFromDomain(String header_from) { 
     super.setHeaderFromDomain(header_from); 
    } 

    @XmlPath("auth_results/dkim/@result") 
    protected void setDkimResult(String result) { 
     super.setDkimResult(result); 
    } 

    @XmlPath("auth_results/dkim/@d") 
    protected void setDkimDomain(String d) { 
     super.setDkimDomain(d); 
    } 

    @XmlPath("auth_results/spf/@result") 
    protected void setSpfResult(String result) { 
     super.setSpfResult(result); 
    } 
} 

樣本數據

<?xml version="1.0" encoding="UTF-8" ?> 
<feedback> 
    <submitter> 
    <org_name>specific</org_name> 
    <email>[email protected]</email> 
    </submitter> 
    <date_range> 
    <begin>20110511</begin> 
    <end>20110511</end> 
    </date_range> 
    <report_id>682417472261065178</report_id> 
    <authstats> 
    <record> 
     <row source_ip="184.106.220.108" count="8" policy_domain="test.net" policy="none" action_taken="none" /> 
     <identities envelope_from="test.net" header_from="test.net" /> 
     <auth_results> 
     <dkim result="neutral" d="test.net" /> 
     <spf domain="test.net" identity="spf_envelope_from" result="pass" /> 
     </auth_results> 
    </record> 
    <record> 
     <row source_ip="50.56.76.41" count="6" policy_domain="test.net" policy="none" action_taken="none" /> 
     <identities envelope_from="test.net" header_from="test.net" /> 
     <auth_results> 
     <dkim result="neutral" d="test.net" /> 
     <spf domain="test.net" identity="spf_envelope_from" result="softfail" /> 
     </auth_results> 
    </record> 
    <record> 
     <row source_ip="50.56.76.41" count="6" policy_domain="test.net" policy="none" action_taken="none" /> 
     <identities envelope_from="test.net" header_from="test.net" /> 
     <auth_results> 
     <dkim result="none" d="" /> 
     <spf domain="test.net" identity="spf_envelope_from" result="softfail" /> 
     </auth_results> 
    </record> 
    <record> 
     <row source_ip="184.106.220.108" count="6" policy_domain="test.net" policy="none" action_taken="none" /> 
     <identities envelope_from="test.net" header_from="test.net" /> 
     <auth_results> 
     <dkim result="pass" d="test.net" /> 
     <spf domain="test.net" identity="spf_envelope_from" result="pass" /> 
     </auth_results> 
    </record> 
    <record> 
     <row source_ip="50.56.76.41" count="8" policy_domain="test.net" policy="none" action_taken="none" /> 
     <identities envelope_from="test.net" header_from="test.net" /> 
     <auth_results> 
     <dkim result="pass" d="test.net" /> 
     <spf domain="test.net" identity="spf_envelope_from" result="softfail" /> 
     </auth_results> 
    </record> 
    <record> 
     <row source_ip="184.106.220.108" count="6" policy_domain="test.net" policy="none" action_taken="none" /> 
     <identities envelope_from="test.net" header_from="test.net" /> 
     <auth_results> 
     <dkim result="none" d="" /> 
     <spf domain="test.net" identity="spf_envelope_from" result="pass" /> 
     </auth_results> 
    </record> 
    </authstats> 
</feedback> 

回答

1

問題

不一致的行爲是由於屬性被覆蓋的子類。 MOXy認爲父類和子類中的屬性被映射,並且取決於處理的順序,您會看到一個或另一個行爲。

解決方案#1

你需要告訴莫西父屬性不會映射,您可以通過在AggregateRecordAggregateReport類指定@XmlAccessorType(XmlAccessType.NONE)做到這一點:

import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlAccessType; 

@XmlAccessorType(XmlAccessType.NONE) 
public class AggregateRecord { 
    ... 
} 

然後指定@XmlAccessorType(XmlAccessType.PROPERTY)SpecificAggregateRecordSpecificAggregateReport類別:

import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlAccessType; 

@XmlAccessorType(XmlAccessType.PROPERTY) 
public class SpecificAggregateRecord extends AggregateRecord { 

解決方案#2

如果您正在覆蓋在子類中的存取僅用於應用你可能要考慮使用莫西的外部映射文件,而不是一個映射的目的。下面是一個例子:

請讓我知道如果你有興趣探索這個選項。

+1

我終於回到了這一點,雖然我不得不指定'XmlAccessType.FIELD'而不是'PROPERTY',它似乎現在一直工作。 – Guildencrantz 2011-07-04 23:08:11