2016-02-14 14 views
17

In un'applicazione C# ho bisogno di controllare l'output del mio algoritmo, che è un albero XML contro un altro albero XML per vedere come sono simili. (l'ordine dei nodi è importante, ma la struttura (nodi annidati), i nomi dei nodi sono più importanti). Forse il numero di adds, removes e moves che si verifica in alcuni algoritmi "Tree Edit distance" è un buon indicatore. Ma le risposte sono più pacchetti Java o Python.Come controllare la somiglianza di due alberi Xml (Tree Edit Distance in C#)

Quindi, ho provato a utilizzare XMLDiffPatch, funziona correttamente quando il tipo di algoritmo è impostato su Precise. Tuttavia il suo punto negativo è che genera solo un file DiffGram che deve essere analizzato per trovare il numero di operazioni. Inoltre, è molto bacato e genera OutOfRangeException per alcuni alberi XML. Inoltre non sono riuscito a trovare pacchetti migliori per il mio scopo per .Net. Ci sono alcuni Xml difference packages ma forse nessuno o alcuni di loro sono su Tree Edit Distance.

Un esempio:

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

A:

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

Per convertire il primo Xml al secondo, è necessario rimuovere E e F (2 costi), allora è necessario rimuovere B (ma non il suo sottostruttura) e aggiungere G. Quindi i costi totali sono 4.

Quindi, come so qui non dovrei chiedere pacchetti e strumenti, chiedo un semplice algoritmo o (albero algoritmo di distanza in .Net) per farlo. Questo è il mio proprio algoritmo per controllare somiglianza e ignorare piccola differenza (Avere uno o pochi nodi nidificati), ma è molto elementare e solo per un punto di partenza:

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

Due alberi sono classificati 0 (= somiglianza massimo) dal vostro algoritmo, se i nomi dei nodi principali sono uguali e un nodo radice ha senza figli e l'altra una quantità arbitraria di loro. È intenzionale? – Haukinger

+0

@Haukinger L'ho modificato un po ', ma ha molte frodi, comunque è solo un punto di partenza. – Ahmad

+1

Potresti fornire esempi di snippet XML per primari e secondari quali, a tuo parere, sono ancora simili? sarebbe davvero utile per lavorare sulla soluzione. –

risposta

3

Microsoft ha un'API per questo. controllare this. Questo potrebbe essere il vecchio riferimento alle DLL ma solo per te le informazioni, devi usare qualcosa di simile. C: \ Windows \ assembly \ GAC \ XmlDiffPatch \ 1.0.8.28__b03f5f7f11d50a3a \ XmlDiffPatch.dll

Problemi correlati