2016-02-14 10 views
17

In einer C# -Anwendung muss ich die Ausgabe meines Algorithmus überprüfen, der ein XML-Baum gegen einen anderen XML-Baum ist, um zu sehen, wie sie ähnlich sind. (Knoten Reihenfolge ist wichtig, aber die Struktur (verschachtelte Knoten), Namen der Knoten sind wichtiger). Vielleicht ist die Anzahl der adds, removes und moves, die in einigen "Tree Edit distance" Algorithmen auftreten, ein guter Indikator. Aber die Antworten sind mehr Java oder Python-Pakete.So überprüfen Sie die Ähnlichkeit zweier Xml-Bäume (Tree Edit Distance in C#)

Also, ich habe versucht, XMLDiffPatch zu verwenden, funktioniert es gut, wenn der Algorithmus-Typ auf Precise festgelegt ist. Allerdings ist es ein schlechter Punkt, dass es nur eine DiffGram Datei erzeugt, die analysiert werden muss, um die Anzahl der Operationen zu finden. Außerdem ist es sehr fehlerhaft und generiert OutOfRangeException für einige XML-Bäume. Ich konnte auch keine besseren Pakete für meine Zwecke für .Net finden. Es gibt einige Xml difference packages aber vielleicht sind keine oder wenige von ihnen auf Tree Edit Distance.

Ein Beispiel:

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

An:

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

Um den ersten Xml in den zweiten zu konvertieren, müssen Sie E und F (2 Kosten) entfernen, dann müssen Sie B entfernen (aber nicht seinen Unterbaum) und G hinzufügen. Dann werden die Gesamtkosten ist 4.

So, wie ich hier weiß ich nicht für Pakete und Tools stellen sollten, bitte ich um einen einfachen Algorithmus oder (Baum Editierdistanz Algorithmus in .Net), das zu tun. Dies ist mein eigene Algorithmus Ähnlichkeit zu überprüfen und ignorieren kleinen Unterschied (mit einem oder wenigen verschachtelten Knoten), aber es ist sehr primäres und nur für einen Startpunkt:

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

Zwei Bäume werden von Ihrem Algorithmus mit 0 bewertet (= maximale Ähnlichkeit), wenn die Namen der Wurzelknoten gleich sind und ein Wurzelknoten vorhanden ist keine Kinder und der andere eine willkürliche Menge von ihnen. Ist das beabsichtigt? – Haukinger

+0

@Haukinger Ich habe es ein bisschen modifiziert, aber es hat viele Betrügereien, jedenfalls ist es nur ein Ausgangspunkt. – Ahmad

+1

Könnten Sie bitte Beispiele für XML-Snippets für primäre und sekundäre XML-Dateien nennen, die Ihrer Meinung nach immer noch ähnlich sind? wäre wirklich hilfreich, um an der Lösung zu arbeiten. –

Antwort

3

Microsoft hat eine API für die. Überprüfen Sie this. Dies kann alte DLL-Referenz sein, aber nur für Sie Informationen, müssen Sie so etwas verwenden. C: \ Windows \ Assembly \ GAC \ XmlDiffPatch \ 1.0.8.28__b03f5f7f11d50a3a \ XmlDiffPatch.dll

Verwandte Themen