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;
}
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
@Haukinger L'ho modificato un po ', ma ha molte frodi, comunque è solo un punto di partenza. – Ahmad
Potresti fornire esempi di snippet XML per primari e secondari quali, a tuo parere, sono ancora simili? sarebbe davvero utile per lavorare sulla soluzione. –