2016-02-14 8 views
17

W aplikacji C# muszę sprawdzić wynik mojego algorytmu, który jest drzewem XML względem innego drzewa XML, aby zobaczyć, jak są one podobne. (Kolejność węzłów jest ważna, ale ważniejsza jest struktura (zagnieżdżone węzły), nazwy węzłów). Być może dobrym przykładem jest liczba adds, removes i , która występuje w niektórych algorytmach "Tree Edit distance". Ale odpowiedzi to więcej pakietów Java lub Python.Jak sprawdzić podobieństwo dwóch drzewek Xml (Tree Edit Distance in C#)

Tak więc, próbowałem użyć XMLDiffPatch, działa dobrze, gdy typ algorytmu jest ustawiony na Precise. Jednak wadą jest to, że po prostu generuje plik DiffGram, który należy przeanalizować, aby znaleźć liczbę operacji. Co więcej, jest bardzo błędny i generuje OutOfRangeException dla niektórych drzewek XML. Nie mogłem też znaleźć lepszych pakietów dla mojego celu .Net. Istnieje pewna liczba: Xml difference packages, ale być może żadna lub kilka z nich nie ma wartości Tree Edit Distance.

Przykład:

<A> 
    <B> 
    <C></C> 
    <D></D> 
    <E> 
     <F> 
     </F> 
    </E> 
    </B> 
</A> 

Do:

<A>  
    <C></C> 
    <D></D> 
    <G></G> 
</A> 

Aby przekonwertować pierwszy XML do drugiego, trzeba usunąć E i F (2 koszty), a następnie trzeba usunąć B (ale nie jego podrzędnego drzewa) i dodać G. Następnie całkowite koszty wynoszą 4.

Tak więc, jak wiem, nie powinienem pytać o pakiety i narzędzia, proszę o wykonanie prostego algorytmu lub (algorytmu edycji drzewa w .Net), aby to zrobić. To jest mój własny algorytm, by sprawdzić podobieństwo i ignoruje drobne różnice (posiadające jeden lub kilka zagnieżdżonych węzłów), ale jest bardzo podstawowy i po prostu za punkt wyjścia:

public int XMLCompare(XmlNode primary, XmlNode secondary) 
{ 
    int x = 0; 
    if (secondary == null || primary == null) 
     return 1; 

    if (secondary.ChildNodes.Count == 1 && primary.ChildNodes.Count > 1) 
    { 
     x += XMLCompare(primary, secondary.ChildNodes[0]); 
    } 
    else if (secondary.ChildNodes.Count > 1 && primary.ChildNodes.Count == 1) 
    { 
     x += XMLCompare(primary.ChildNodes[0], secondary); 
    } 
    else 
    { 
     if (primary.Name.ToLower() != secondary.Name.ToLower()) 
      x = 1; 
     int m = Math.Max(primary.ChildNodes.Count, secondary.ChildNodes.Count); 
     for (int i = 0; i < m i++) 
     { 
      x += XMLCompare(
      i < primary.ChildNodes.Count ? primary.ChildNodes[i] : null, 
      i < secondary.ChildNodes.Count ? secondary.ChildNodes[i] : null); 

     } 
    } 

    return x; 
} 
+0

Dwa drzewa mają 0 (= maksymalne podobieństwo) według algorytmu, jeśli nazwy węzłów głównych są równe i jeden węzeł główny ma żadnych dzieci, a druga dowolna ich ilość. Czy to jest zamierzone? – Haukinger

+0

@Haukinger Zmodyfikowałem go trochę, ale ma wiele oszustów, w każdym razie to tylko punkt wyjścia. – Ahmad

+1

Czy możesz podać przykłady fragmentów kodu XML dla elementów podstawowych i dodatkowych, które Twoim zdaniem są nadal podobne? byłoby naprawdę pomocne w pracy nad rozwiązaniem. –

Odpowiedz

3

Microsoft ma API dla tego. sprawdź this. Może to być stary odnośnik dll, ale tylko dla Ciebie informacji, musisz użyć czegoś takiego. C: \ Windows \ assembly \ GAC \ XmlDiffPatch \ 1.0.8.28__b03f5f7f11d50a3a \ XmlDiffPatch.dll