2013-03-14 55 views
0

我被給了XML和模式文件。我的目標是輸出XML中的所有數據(無重複),並在出生日期前排列此列表。目前我得到的所有數據都打印出來(有重複的),我不知道接下來要做什麼。我嘗試了不同的東西,但沒有成功。排序和比較來自Java的XML

回答

0

編輯

再次閱讀文章後,我意識到我需要刪除的DUP過這樣:

可以使用TreeSet徵收unqiueness和排序DOB - 我相信,隨着一個人相同的名字,姓氏和出生日期是同一個人。

首先,我會將你的Node包裝在一個實現了Comparable的類中,並且也獲得了你擁有的所有屬性。包裝需要實現Comparable,因爲TreeSet使用此方法來判斷元素是否不同(a.compareTo(b) != 0)以及如何對它們進行排序。

public static final class NodeWrapper implements Comparable<NodeWrapper> { 

    private static final SimpleDateFormat DOB_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); 
    private final Element element; 
    private final Date dob; 
    private final String firstName; 
    private final String surName; 
    private final String sex; 

    public NodeWrapper(final Node node) { 
     this.element = (Element) node; 
     try { 
      this.dob = DOB_FORMAT.parse(initDateOfBirth()); 
     } catch (ParseException ex) { 
      throw new RuntimeException("Failed to parse dob", ex); 
     } 
     this.firstName = initFirstName(); 
     this.surName = initSurnameName(); 
     this.sex = initSex(); 
    } 

    private String initFirstName() { 
     return getNodeValue("firstname"); 
    } 

    private String initSurnameName() { 
     return getNodeValue("surname"); 
    } 

    private String initDateOfBirth() { 
     return getNodeValue("dateofbirth"); 
    } 

    private String initSex() { 
     return getNodeValue("sex"); 
    } 

    private String getNodeValue(final String name) { 
     return element.getElementsByTagName(name).item(0).getTextContent(); 
    } 

    public Node getNode() { 
     return element; 
    } 

    Date getDob() { 
     return dob; 
    } 

    public String getFirstName() { 
     return firstName; 
    } 

    public String getSurName() { 
     return surName; 
    } 

    public String getDateOfBirth() { 
     return DOB_FORMAT.format(dob); 
    } 

    public String getSex() { 
     return sex; 
    } 

    public int compareTo(NodeWrapper o) { 
     int c; 
     c = getDob().compareTo(o.getDob()); 
     if (c != 0) { 
      return c; 
     } 
     c = getSurName().compareTo(o.getSurName()); 
     if (c != 0) { 
      return c; 
     } 
     return getFirstName().compareTo(o.getFirstName()); 
    } 

    @Override 
    public int hashCode() { 
     int hash = 5; 
     hash = 47 * hash + (this.dob != null ? this.dob.hashCode() : 0); 
     hash = 47 * hash + (this.firstName != null ? this.firstName.hashCode() : 0); 
     hash = 47 * hash + (this.surName != null ? this.surName.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (obj == null) { 
      return false; 
     } 
     if (getClass() != obj.getClass()) { 
      return false; 
     } 
     final NodeWrapper other = (NodeWrapper) obj; 
     if (this.dob != other.dob && (this.dob == null || !this.dob.equals(other.dob))) { 
      return false; 
     } 
     if ((this.firstName == null) ? (other.firstName != null) : !this.firstName.equals(other.firstName)) { 
      return false; 
     } 
     if ((this.surName == null) ? (other.surName != null) : !this.surName.equals(other.surName)) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "FirstName: " + getFirstName() + ". Surname: " + getSurName() + ". DOB: " + getDateOfBirth() + ". Sex: " + getSex() + "."; 
    } 
} 

所以,如果出生,姓和名字的日期都是平等的,我們假設它是同一個人 - 我們返回0,這是很好的做法,如果以這種方式使用compareTo使其與equals一致,所以如果a.compareTo(b)==0然後a.equals(b),我也添加了所需的equalshashCode方法。

現在你可以使用代碼中的TreeSet,它會自動排序,並保證unqiueness:

final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("file.xml")); 

final Set<NodeWrapper> inimesteList = new TreeSet<NodeWrapper>(); 

final NodeList isa = doc.getElementsByTagName("isa"); 
for (int i = 0; i < isa.getLength(); i++) { 
    inimesteList.add(new NodeWrapper(isa.item(i))); 
} 
final NodeList ema = doc.getElementsByTagName("ema"); 
for (int i = 0; i < ema.getLength(); i++) { 
    inimesteList.add(new NodeWrapper(ema.item(i))); 
} 
final NodeList isik = doc.getElementsByTagName("isik"); 
for (int i = 0; i < isik.getLength(); i++) { 
    inimesteList.add(new NodeWrapper(isik.item(i))); 
} 
System.out.println(); 
System.out.println("Total: " + inimesteList.size()); 

for (final NodeWrapper nw : inimesteList) { 
    System.out.println(nw); 
} 

我還添加了一個toString方法和使用的打印節點 - 這使得代碼更清潔。

Document雖然看起來比JAXB簡單,但卻充滿了這種乏味。因爲你已經有一個模式,我會強烈建議,你做出了xjc和JAXB unmarshalling的舉動 - 這將使這種東西的時間更容易陷入困境。

+0

你的'Node'和'Element'的類型是什麼?你有正確的導入嗎?它們應該像你的代碼片段中的'org.w3c.dom'一樣。當然,你不能做'Element node =(Element)inimesteList.get(i)'。首先,如果不應該是一個'List',而是一個'Set',所以沒有'get'方法。其次'NodeWrapper'不是'Node'!您需要使用'getNode'來獲取包裝的'Node'。 – 2013-03-14 13:13:00

+0

看起來很好,什麼'構造函數NodeWrapper(ode)...',這是一個錯字?什麼是「頌歌」? – 2013-03-14 13:19:27

+0

你在哪裏把'NodeWrapper'類放在另一個類文件中?在這種情況下檢查其進口。 – 2013-03-14 13:21:04

1

HashSet將取決於Node.equals()方法來確定相等性,並且您將添加不同節點,儘管具有相同的基礎文本。從the doc

添加指定的元素e這套如果此集合不包含 構件e2,使得(E == NULL E2 == NULL:e.equals(E2))

我會從Node中提取底層文本(String),而HashSet<String>將正確確定唯一性。

0

它更好地創建一個具有單節點詳細信息的Java Bean(POJO)。覆蓋equals()hashcode()相同。將所有節點數據存儲到Bean列表中。然後使用LinkedHashSet刪除重複項。執行Comparable或使用ComparatorCollections.sort()對其進行分類。


擴展或在另一個類中封裝Node並重寫在同一equals()hashcode()。將所有Node存儲到新類實例的List中。然後使用LinkedHashSet刪除重複項。執行Comparable或使用ComparatorCollections.sort()對其進行分類。