2017-05-04 22 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> 

IのみANを適用するElementSelectors.conditionalBuilder(https://github.com/xmlunit/user-guide/wiki/SelectingNodes#conditional-elementselectors)と組み合わせて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(); 
    } 

は、二つの言語(EN、IT)と2つのコード(10000-1,30000-3)がされていることが、情報であり、削除されました(置き換えられません)、FIRSTNAMEが変更されました。

XMLユニット(DiffBuilder)の有無にかかわらず、これらの情報を取得するにはどうすればよいですか?

ありがとうございました!

答えて

0

コンストラクタDefaultNodeMatcherに3つのElementSelectorを使用し、複数の条件を持つ1つのElementSelectorを使用することには微妙な違いがあります。

も一見

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

のように書くことができあなたが3つのセレクタを達成したい、これは同じことをやっているようだが、それはしていません。実際にはうまくいくでしょう。ここで私はあなたの例から得るものです:だからここ

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はVALUELANGUAGEを見たとき、あなたが構築したen最初の条件付きElementSelectorは、すべての候補LANGUAGE要素に対してfalseを返します。それだけでCODE要素に興味があるようにも、あなたのケースでfalseを返します -

ElementSelectorが求められますマルチ引数DefaultNodeMatcherコンストラクタを使用して

。そして第3の ElementSelectorが参照され、 LANGUAGEという名前のテスト要素をうまく受け入れることになります。

Predicatetrueを返すとすぐに、結合されたセレクタより上に設定したElementSelectorを使用しても、いずれの代替方法も決して参照しません。これは、セレクタがfalseを返すと、LANGUAGE要素の第2の考えがなくなることを意味します。

私は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 –