2017-05-04 12 views
0

我在將xml文檔中的各種元素與XMLUnit(2.2.1)進行比較時遇到了問題。在我的文檔中有幾個xml元素,我想知道 是否彼此不同。但是,我不想以相同的方式比較所有xml元素。有時我只是想通過他們的名字來比較他們。在其他情況下,我想通過名稱和屬性或名稱和文本進行比較。XML單元 - 在不同的xml元素上使用自定義元素選擇器

下面是一個例子(見註釋)

控制

<?xml version="1.0" encoding="UTF-8"?> 
<ROOT> 
    <LANGUAGES> 
     <!-- Compare LANGUAGE by Name and Attribute --> 
     <LANGUAGE VALUE="DE" /> 
     <LANGUAGE VALUE="EN" /> 
     <LANGUAGE VALUE="IT" /> 
     <LANGUAGE VALUE="FR" /> 
    </LANGUAGES> 
    <CODES> 
     <!-- Compare CODE by Name and Text --> 
     <CODE>10000-1</CODE> 
     <CODE>20000-2</CODE> 
     <CODE>30000-3</CODE> 
     <CODE>40000-4</CODE> 
    </CODES> 
    <CONTACT> <!-- Compare CONTACT and Children just by Name --> 
     <FIRSTNAME>Max</FIRSTNAME> 
     <SURNAME>Mustermann</SURNAME> 
    </CONTACT> 
</ROOT> 

測試:

<?xml version="1.0" encoding="UTF-8"?> 
<ROOT> 
    <LANGUAGES> 
     <!-- Compare LANGUAGE by Name and Attribute --> 
     <LANGUAGE VALUE="DE" /> 
     <LANGUAGE VALUE="FR" /> 
    </LANGUAGES> 
    <CODES> 
     <!-- Compare CODE by Name and Text --> 
     <CODE>20000-2</CODE> 
     <CODE>40000-4</CODE> 
    </CODES> 
    <CONTACT> <!-- Compare CONTACT and Children by Name --> 
     <FIRSTNAME>Tim</FIRSTNAME> 
     <SURNAME>Mustermann</SURNAME> 
    </CONTACT> 
</ROOT> 

我試圖聯合ElementSelectors與ElementSelectors.conditionalBuilder(https://github.com/xmlunit/user-guide/wiki/SelectingNodes#conditional-elementselectors)只適用於一個特定元素上的ElementSelector(whenElementIsNamed)。也許這不是我想要達到的目標。

這是我的代碼用於測試:

public void xmlDiff() { 
    String control = getControlDocument(); // 
    String test = getTestDocument(); // 
    Diff myDiff = DiffBuilder.compare(control)// 
      .withTest(test) // 
      .ignoreWhitespace() // 
      .ignoreComments() // 
      .checkForSimilar() // 
      .withNodeMatcher(new DefaultNodeMatcher(partialElementSelector("LANGUAGE", ElementSelectors.byNameAndAllAttributes), partialElementSelector("CODE",ElementSelectors.byNameAndText), ElementSelectors.byName)) // 
      .build(); 
    assertThat(myDiff.hasDifferences()).isTrue(); // 
} 

    private ElementSelector partialElementSelector(final String expectedName, final ElementSelector elementSelector) { 
     return ElementSelectors.conditionalBuilder().whenElementIsNamed(expectedName).thenUse(elementSelector).build(); 
    } 

我真正需要的是信息,這兩種語言(英語,IT)和兩個碼(10000-1,30000-3)已刪除(未替換)和FIRSTNAME已更改。

我該如何獲得那些有或沒有XML單元(DiffBuilder)的信息?

謝謝你的幫助!

回答

0

DefaultNodeMatcher的構造函數中使用三個ElementSelector並在多個條件下使用單個ElementSelector存在細微差異。

要實現與三個選擇什麼也可以寫爲

ElementSelectors.conditionalBuilder() 
    .whenElementIsNamed("LANGUAGE") 
    .thenUse(ElementSelectors.byNameAndAllAttributes) 
    .whenElementIsNamed("CODE") 
    .thenUse(ElementSelectors.byNameAndText) 
    .elseUse(ElementSelectors.byName) 
    .build(); 

乍一看,這似乎是做同樣的,但事實並非如此。實際上它會起作用。以下是我從你的例子得到:

Expected child nodelist length '4' but was '2' - comparing <LANGUAGES...> at /ROOT[1]/LANGUAGES[1] to <LANGUAGES...> at /ROOT[1]/LANGUAGES[1] (DIFFERENT) 
Expected child 'LANGUAGE' but was 'null' - comparing <LANGUAGE...> at /ROOT[1]/LANGUAGES[1]/LANGUAGE[2] to <NULL> (DIFFERENT) 
Expected child 'LANGUAGE' but was 'null' - comparing <LANGUAGE...> at /ROOT[1]/LANGUAGES[1]/LANGUAGE[3] to <NULL> (DIFFERENT) 
Expected child nodelist length '4' but was '2' - comparing <CODES...> at /ROOT[1]/CODES[1] to <CODES...> at /ROOT[1]/CODES[1] (DIFFERENT) 
Expected child 'CODE' but was 'null' - comparing <CODE...> at /ROOT[1]/CODES[1]/CODE[1] to <NULL> (DIFFERENT) 
Expected child 'CODE' but was 'null' - comparing <CODE...> at /ROOT[1]/CODES[1]/CODE[3] to <NULL> (DIFFERENT) 
Expected text value 'Max' but was 'Tim' - comparing <FIRSTNAME ...>Max</FIRSTNAME> at /ROOT[1]/CONTACT[1]/FIRSTNAME[1]/text()[1] to <FIRSTNAME ...>Tim</FIRSTNAME> at /ROOT[1]/CONTACT[1]/FIRSTNAME[1]/text()[1] (DIFFERENT) 

因此,這裏發生了什麼:當XMLUnit測試着眼於LANGUAGEVALUEen第一個條件ElementSelector你已經建立將返回false對所有候選LANGUAGE元素。

當使用多ARG DefaultNodeMatcher構造下一個ElementSelector將被要求 - 這也將在你的情況下返回false,因爲它是隻關心CODE元素。然後查詢第三個ElementSelector,它將愉快地接受名爲LANGUAGE的任何測試元素。

當我使用上面設置的單個ElementSelector時,只要Predicate已返回true,組合選擇器將不會查詢任何替代方案。這意味着,一旦選擇器返回false,就不會有LANGUAGE元素的第二個想法。

我會嘗試用您的示例更新https://github.com/xmlunit/user-guide/wiki/SelectingNodes#nodematcher,並且希望能夠幫助您改進文檔。

+0

謝謝Stefan,那就是我一直在尋找的:)! – fwshngtn

+0

我已添加https://github.com/xmlunit/user-guide/wiki/SelectingNodes#using-more-than-one-elementselector-at-the-same-time –

+0

很高興爲您效力@fwshngtn –