/// <summary> /// Vergleicht zwei Knotenbäume. Beide Knotenbäume werden dabei verändert. /// </summary> /// <param name="k1">Der eine Knotenbaum.</param> /// <param name="k2">Der andere Knotenbaum.</param> /// <returns><code>null</code>, falls beide Knoten identisch sind oder der geänderte /// k1-Knoten mit den Unterschieden.</returns> public Knoten Diff(Knoten k1, Knoten k2) { subtract(k1, k2); if (!k1.hasKinder() && !k2.hasKinder()) { if (k1.Equals(k2)) { //beide Bäume sind identisch return(null); } } return(k1); }
/** * Ermittelt eine Stringrepräsentation für den angegebenen Knoten. * @param k Der Knoten. * @return Die Stringdarstellung. */ private static String getKnotenAsString(Knoten k) { StringBuilder sb = new StringBuilder(); sb.Append(k.elementName); foreach (var e in k.attributes) { sb.Append(" "); sb.Append(e.Key); sb.Append("=\""); sb.Append(e.Value); sb.Append("\""); } return(sb.ToString()); }
/** * Erzeugt aus dem angegebenen Node einen Knoten. Die Kinder werden berücksichtigt. * @param node Der zu konvertierende Node. * @return Ein Knoten, der dem Node entspricht. */ public static Knoten createOf(XmlNode node) { Knoten parent = createKnoten(node); if (parent == null) { return(null); } XmlNodeList kids = node.ChildNodes; for (int i = 0, cnt = kids.Count; i < cnt; i++) { Knoten kind = createOf(kids.Item(i)); if (kind != null) { parent.addKind(kind); } } return(parent); }
private string diffWithDiffy(string firstXml, string secondXml) { try { XmlNode eines = createDOM(XmlReader.Create(firstXml.ToStream())); XmlNode anderes = createDOM(XmlReader.Create(secondXml.ToStream())); Knoten ersterKnoten = Knoten.createOf(eines); Knoten andererKnoten = Knoten.createOf(anderes); DiffEngine diff = new DiffEngine(); Knoten res = diff.Diff(ersterKnoten, andererKnoten); if (res == null) { return("XML files are equal"); } else { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.Encoding = XSConfiguration.Instance.Config.Encoding; XmlDocument result = res.ToString().ToXmlDocument(); StringBuilder sb = new StringBuilder(); using (XmlWriter w = XmlWriter.Create(sb, settings)) { result.WriteTo(w); } return(sb.ToString()); } } catch (Exception ex) { return(ex.Message); } }
/** * Fügt den angegebenen Knoten als Kind dieses Knotens hinzu. * @param kind Das neue Kind. */ public void addKind(Knoten kind) { kinder.Add(kind); }
/** * {@inheritDoc} */ public override bool Equals(Object obj) { if (this == obj) { return(true); } if (obj == null) { return(false); } if (GetType() != obj.GetType()) { return(false); } Knoten other = (Knoten)obj; if (attributes == null) { if (other.attributes != null) { return(false); } } else if (!attributes.Equals(other.attributes)) { return(false); } if (elementName == null) { if (other.elementName != null) { return(false); } } else if (!elementName.Equals(other.elementName)) { return(false); } if (kinder == null) { if (other.kinder != null) { return(false); } } else if (!kinder.Equals(other.kinder)) { return(false); } if (text == null) { if (other.text != null) { return(false); } } else if (!text.Equals(other.text)) { return(false); } if (typ == null) { if (other.typ != null) { return(false); } } else if (!typ.Equals(other.typ)) { return(false); } return(true); }
/** * Prüft, ob dieser und der angegebene Knoten gleich sind. Die Kinder werden dabei * nicht berücksichtigt. Ebenso wird Whitespace im Text nicht berücksichtigt. * @param other Der zu vergleichende Knoten. * @return <code>true</code>, falls die beiden Knoten gleich sind. * @see #equals(Object) */ public bool equalsWithoutChildren(Knoten other) { if (GetType() != other.GetType()) { Debug.Fail(""); return(false); } if (attributes == null) { if (other.attributes != null) { return(false); } } else if (!attributes.Equals(other.attributes)) { return(false); } if (elementName == null) { if (other.elementName != null) { return(false); } } else if (!elementName.Equals(other.elementName)) { return(false); } // if (kinder == null) { // if (other.kinder != null) { // return false; // } // } else if (!kinder.equals(other.kinder)) { // return false; // } if (text == null) { if (other.text != null) { return(false); } } else { //Bei unterschiedlichen Kindern stimmt oft auch der Whitespace nicht String othertext = other.text == null ? null : other.text.Trim(); if (!text.Trim().Equals(othertext)) { return(false); } } if (typ == null) { if (other.typ != null) { return(false); } } else if (!typ.Equals(other.typ)) { return(false); } return(true); }
/** * Löscht das angegebene Kind * @param kind Das zu löschende Kind */ public void removeKind(Knoten kind) { bool success = kinder.Remove(kind); Debug.Assert(success, "Kind nicht gefunden: " + kind.ToString()); }
/** * Subtrahiert die beiden Knoten voneinander. * @param minuend Der Minuend. * @param subtrahend Der Subtrahend. */ private void subtract(Knoten minuend, Knoten subtrahend) { //Die Kinder können nicht sofort gelöscht werden, da sich sonst die Liste ändert //und man nicht mehr einfach durchiterieren kann List <Knoten> zuLoeschendeKinderMinu = new List <Knoten>(); List <Knoten> zuLoeschendeKinderSubt = new List <Knoten>(); List <Knoten> hinzuzufuegendeKinder = new List <Knoten>(); foreach (Knoten kind_minu in minuend.getKinder()) { Knoten kind_subt = getKindWie(kind_minu, subtrahend); if (kind_subt != null) { subtract(kind_minu, kind_subt); if (!kind_minu.hasKinder() && !kind_subt.hasKinder()) { if (kind_minu.Equals(kind_subt)) { zuLoeschendeKinderMinu.Add(kind_minu); zuLoeschendeKinderSubt.Add(kind_subt); kind_minu.setIgnoreMe(); kind_subt.setIgnoreMe(); } } else { // } } else { Knoten k = new Knoten( Knoten.KnotenTyp.GELOESCHT, kind_minu.getName(), kind_minu.getText(), kind_minu.getAttributes()); k.setIgnoreMe(); hinzuzufuegendeKinder.Add(k); zuLoeschendeKinderMinu.Add(kind_minu); } } foreach (Knoten loeschMich in zuLoeschendeKinderMinu) { minuend.removeKind(loeschMich); } foreach (Knoten loeschMich in zuLoeschendeKinderSubt) { subtrahend.removeKind(loeschMich); } if (subtrahend.hasKinder()) { foreach (Knoten hinzugefuegtesKind in subtrahend.getKinder()) { Knoten kind_minu = getKindWie(hinzugefuegtesKind, minuend); if (kind_minu == null) { Knoten k = new Knoten( Knoten.KnotenTyp.HINZUGEFUEGT, hinzugefuegtesKind.getName(), hinzugefuegtesKind.getText(), hinzugefuegtesKind.getAttributes()); k.setIgnoreMe(); hinzuzufuegendeKinder.Add(k); } } } foreach (Knoten neu in hinzuzufuegendeKinder) { minuend.addKind(neu); } }
/** * Ermittelt aus dem Knotenbaum "parent" ein Kind, das so ähnlich ist wie "beispiel" * @param beispiel * @param parent * @return Das ähnliche Kind oder <code>null</code>, falls kein ähnliches Kind * existiert. */ private static Knoten getKindWie(Knoten beispiel, Knoten parent) { Knoten gefunden = null; Knoten gefunden2 = null; int anzGefunden = 0; ICollection <Knoten> kids = parent.getKinder(); foreach (Knoten kid in kids) { if (kid.isIgnoreMe()) { continue; } if (kid.equalsWithoutChildren(beispiel)) { if (gefunden == null) { //erstes übernehmen gefunden = kid; } anzGefunden++; } } //wenn mehrere Kinder gemäß equalsWithoutChildren gefunden wurden, dann Suche eingrenzen //Prüfen, ob die Knoten überhaupt Kinder haben if (anzGefunden > 1) { anzGefunden = 0; foreach (Knoten kid in kids) { if (kid.isIgnoreMe()) { continue; } if (kid.equalsWithoutChildren(beispiel)) { if (kid.getKinder().Count == beispiel.getKinder().Count) { if (gefunden2 == null) { gefunden2 = kid; } anzGefunden++; } } } } //wenn mehrere Kinder gemäß equalsWithoutChildren && Kinderanzahl gefunden wurden, dann Suche eingrenzen //Prüfen, ob die Knoten überhaupt Kinder haben if (anzGefunden > 1) { foreach (Knoten kid in kids) { if (kid.isIgnoreMe()) { continue; } if (kid.Equals(beispiel)) { return(kid); } } } if (gefunden2 != null) { return(gefunden2); } else { return(gefunden); } }