private void LoadElement(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo) { XmlDiffElement elem = null; bool bEmptyElement = reader.IsEmptyElement; if (bEmptyElement) { elem = new XmlDiffEmptyElement(reader.LocalName, reader.Prefix, reader.NamespaceURI); } else { elem = new XmlDiffElement(reader.LocalName, reader.Prefix, reader.NamespaceURI); } elem.LineNumber = pInfo.LineNumber; elem.LinePosition = pInfo.LinePosition; ReadAttributes(elem, reader, pInfo); if (!bEmptyElement) { // bool rtn = reader.Read(); // rtn = reader.Read(); reader.Read(); //move to child ReadChildNodes(elem, reader, pInfo); } InsertChild(parent, elem); }
public override XmlNodeOrder ComparePosition(XPathNavigator nav) { XmlDiffNode targetNode = ((XmlDiffNavigator)nav).CurrentNode; // Debug.Assert(false, "ComparePosition is NYI"); if (!(nav is XmlDiffNavigator)) { return(XmlNodeOrder.Unknown); } if (targetNode == this.CurrentNode) { return(XmlNodeOrder.Same); } else { if (this.CurrentNode.ParentNode == null) //this is root { return(XmlNodeOrder.After); } else if (targetNode.ParentNode == null) //this is root { return(XmlNodeOrder.Before); } else //look in the following nodes { if (targetNode.LineNumber + targetNode.LinePosition > this.CurrentNode.LinePosition + this.CurrentNode.LineNumber) { return(XmlNodeOrder.After); } return(XmlNodeOrder.Before); } } }
private void SortChildren(XmlDiffElement elem) { if (elem.FirstChild != null) { XmlDiffNode _first = elem.FirstChild; XmlDiffNode _current = elem.FirstChild; XmlDiffNode _last = elem.LastChild; elem._firstChild = null; elem._lastChild = null; //set flag to ignore child order bool temp = IgnoreChildOrder; IgnoreChildOrder = true; XmlDiffNode _next = null; do { if (_current is XmlDiffElement) { _next = _current._next; } _current._next = null; InsertChild(elem, _current); if (_current == _last) { break; } _current = _next; }while (true); //restore flag for ignoring child order IgnoreChildOrder = temp; } }
private void LoadTopLevelAttribute(XmlDiffNode parent, string text, PositionInfo pInfo, XmlDiffNodeType nt) { XmlDiffCharacterData textNode = new XmlDiffCharacterData(text, nt, this.NormalizeNewline); textNode.LineNumber = pInfo.LineNumber; textNode.LinePosition = pInfo.LinePosition; InsertTopLevelAttributeAsText(parent, textNode); }
private void LoadEntityReference(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo) { XmlDiffEntityReference er = new XmlDiffEntityReference(reader.Name); er.LineNumber = pInfo.LineNumber; er.LinePosition = pInfo.LinePosition; InsertChild(parent, er); }
private void LoadPI(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo) { XmlDiffProcessingInstruction pi = new XmlDiffProcessingInstruction(reader.Name, reader.Value); pi.LineNumber = pInfo.LineNumber; pi.LinePosition = pInfo.LinePosition; InsertChild(parent, pi); }
public override bool MoveToNext() { if (!(_currentNode is XmlDiffAttribute) && _currentNode._next != null) { _currentNode = _currentNode._next; return(true); } return(false); }
public override bool MoveTo(XPathNavigator other) { if (other is XmlDiffNavigator) { _currentNode = ((XmlDiffNavigator)other).CurrentNode; return(true); } return(false); }
public override bool MoveToParent() { if (!(_currentNode is XmlDiffDocument)) { _currentNode = _currentNode.ParentNode; return(true); } return(false); }
public XmlDiffNode() { this._next = null; this._firstChild = null; this._lastChild = null; this._parent = null; this._lineNumber = 0; this._linePosition = 0; }
public override bool MoveToFirstChild() { if ((_currentNode is XmlDiffDocument || _currentNode is XmlDiffElement) && _currentNode.FirstChild != null) { _currentNode = _currentNode.FirstChild; return(true); } return(false); }
private void LoadTextNode(XmlDiffNode parent, string text, PositionInfo pInfo, XmlDiffNodeType nt) { if (!this.IgnoreEmptyTextNodes || !String.IsNullOrEmpty(text)) { XmlDiffCharacterData textNode = new XmlDiffCharacterData(text, nt, this.NormalizeNewline); textNode.LineNumber = pInfo.LineNumber; textNode.LinePosition = pInfo.LinePosition; InsertChild(parent, textNode); } }
public override void WriteContentTo(XmlWriter w) { XmlDiffNode child = FirstChild; while (child != null) { child.WriteTo(w); child = child.NextSibling; } }
private void InsertTopLevelAttributeAsText(XmlDiffNode parent, XmlDiffCharacterData newChild) { if (parent.LastChild != null && (parent.LastChild.NodeType == XmlDiffNodeType.Text || parent.LastChild.NodeType == XmlDiffNodeType.WS)) { ((XmlDiffCharacterData)parent.LastChild).Value = ((XmlDiffCharacterData)parent.LastChild).Value + " " + newChild.Value; } else { parent.InsertChildAfter(parent.LastChild, newChild); } }
public override bool MoveToAttribute(String localName, String namespaceURI) { if (_currentNode is XmlDiffElement) { XmlDiffAttribute _attr = ((XmlDiffElement)_currentNode).GetAttribute(localName, namespaceURI); if (_attr != null) { _currentNode = _attr; return(true); } } return(false); }
public override bool MoveToPrevious() { if (_currentNode != _currentNode.ParentNode.FirstChild) { XmlDiffNode _current = _currentNode.ParentNode.FirstChild; XmlDiffNode _prev = _currentNode.ParentNode.FirstChild; while (_current != _currentNode) { _prev = _current; _current = _current._next; } _currentNode = _prev; return(true); } return(false); }
//sunghonhack public new bool MoveToNextNamespace() { if (_currentNode is XmlDiffAttribute) { XmlDiffAttribute _attr = (XmlDiffAttribute)_currentNode._next; while (_attr != null && !IsNamespaceNode(_attr)) { _attr = (XmlDiffAttribute)_attr._next; } if (_attr != null) { _currentNode = _attr; return(true); } } return(false); }
// This is a helper function for WriteResult. It gets the Xml representation of the different node we wants // to write out and all it's children. private String GetNodeText(XmlDiffNode diffNode, DiffType result) { string text = string.Empty; switch (diffNode.NodeType) { case XmlDiffNodeType.Element: if (result == DiffType.SourceExtra || result == DiffType.TargetExtra) { return(diffNode.OuterXml); } StringWriter str = new StringWriter(); XmlWriter writer = XmlWriter.Create(str); XmlDiffElement diffElem = diffNode as XmlDiffElement; Debug.Assert(diffNode != null); writer.WriteStartElement(diffElem.Prefix, diffElem.LocalName, diffElem.NamespaceURI); XmlDiffAttribute diffAttr = diffElem.FirstAttribute; while (diffAttr != null) { writer.WriteAttributeString(diffAttr.Prefix, diffAttr.LocalName, diffAttr.NamespaceURI, diffAttr.Value); diffAttr = (XmlDiffAttribute)diffAttr.NextSibling; } if (diffElem is XmlDiffEmptyElement) { writer.WriteEndElement(); text = str.ToString(); } else { text = str.ToString(); text += ">"; } writer.Dispose(); break; case XmlDiffNodeType.CData: text = ((XmlDiffCharacterData)diffNode).Value; break; default: text = diffNode.OuterXml; break; } return(text); }
private void InsertChild(XmlDiffNode parent, XmlDiffNode newChild) { if (IgnoreChildOrder) { XmlDiffNode child = parent.FirstChild; XmlDiffNode prevChild = null; while (child != null && (ComparePosition(child, newChild) == NodePosition.After)) { prevChild = child; child = child.NextSibling; } parent.InsertChildAfter(prevChild, newChild); } else { parent.InsertChildAfter(parent.LastChild, newChild); } }
public virtual void InsertChildAfter(XmlDiffNode child, XmlDiffNode newChild) { Debug.Assert(newChild != null); newChild._parent = this; if (child == null) { newChild._next = this._firstChild; this._firstChild = newChild; } else { Debug.Assert(child._parent == this); newChild._next = child._next; child._next = newChild; } if (newChild._next == null) { this._lastChild = newChild; } }
//sunghonhack public new bool MoveToFirstNamespace() { if (_currentNode is XmlDiffElement) { if (((XmlDiffElement)_currentNode).FirstAttribute != null) { XmlDiffAttribute _attr = ((XmlDiffElement)_currentNode).FirstAttribute; while (_attr != null && !IsNamespaceNode(_attr)) { _attr = (XmlDiffAttribute)_attr._next; } if (_attr != null) { _currentNode = _attr; return(true); } } } return(false); }
public override bool MoveToFirst() { if (!(_currentNode is XmlDiffAttribute)) { if (_currentNode.ParentNode.FirstChild == _currentNode) { if (_currentNode.ParentNode.FirstChild._next != null) { _currentNode = _currentNode.ParentNode.FirstChild._next; return(true); } } else { _currentNode = _currentNode.ParentNode.FirstChild; return(true); } } return(false); }
//NodePosition.Before is returned if node2 should be before node1; //NodePosition.After is returned if node2 should be after node1; //In any case, NodePosition.Unknown should never be returned. internal NodePosition ComparePosition(XmlDiffNode node1, XmlDiffNode node2) { int nt1 = (int)(node1.NodeType); int nt2 = (int)(node2.NodeType); if (nt2 > nt1) { return(NodePosition.After); } if (nt2 < nt1) { return(NodePosition.Before); } //now nt1 == nt2 if (nt1 == (int)XmlDiffNodeType.Element) { return(CompareElements(node1 as XmlDiffElement, node2 as XmlDiffElement)); } else if (nt1 == (int)XmlDiffNodeType.Attribute) { return(CompareAttributes(node1 as XmlDiffAttribute, node2 as XmlDiffAttribute)); } else if (nt1 == (int)XmlDiffNodeType.ER) { return(CompareERs(node1 as XmlDiffEntityReference, node2 as XmlDiffEntityReference)); } else if (nt1 == (int)XmlDiffNodeType.PI) { return(ComparePIs(node1 as XmlDiffProcessingInstruction, node2 as XmlDiffProcessingInstruction)); } else if (node1 is XmlDiffCharacterData) { return(CompareTextLikeNodes(node1 as XmlDiffCharacterData, node2 as XmlDiffCharacterData)); } else { //something really wrong here, what should we do??? Debug.Assert(false, "ComparePosition meets an undecision situation."); return(NodePosition.Unknown); } }
public virtual void DeleteChild(XmlDiffNode child) { if (child == this.FirstChild)//delete head { this._firstChild = this.FirstChild.NextSibling; } else { XmlDiffNode current = this.FirstChild; XmlDiffNode previous = null; while (current != child) { previous = current; current = current.NextSibling; } Debug.Assert(current != null); if (current == this.LastChild) //tail being deleted { this._lastChild = current.NextSibling; } previous._next = current.NextSibling; } }
// This function writes the result in XML format so that it can be used by other applications to display the diff private void WriteResult(XmlDiffNode sourceNode, XmlDiffNode targetNode, DiffType result) { if (DontWriteAnythingToOutput) { return; } if (result != DiffType.Success || !DontWriteMatchingNodesToOutput) { _Writer.WriteStartElement(String.Empty, "Node", String.Empty); _Writer.WriteAttributeString(String.Empty, "SourceLineNum", String.Empty, (sourceNode != null) ? sourceNode.LineNumber.ToString() : "-1"); _Writer.WriteAttributeString(String.Empty, "SourceLinePos", String.Empty, (sourceNode != null) ? sourceNode.LinePosition.ToString() : "-1"); _Writer.WriteAttributeString(String.Empty, "TargetLineNum", String.Empty, (targetNode != null) ? targetNode.LineNumber.ToString() : "-1"); _Writer.WriteAttributeString(String.Empty, "TargetLinePos", String.Empty, (targetNode != null) ? targetNode.LinePosition.ToString() : "-1"); } if (result == DiffType.Success) { if (!DontWriteMatchingNodesToOutput) { _Writer.WriteStartElement(String.Empty, "Diff", String.Empty); _Writer.WriteEndElement(); _Writer.WriteStartElement(String.Empty, "Lexical-equal", String.Empty); if (sourceNode.NodeType == XmlDiffNodeType.CData) { _Writer.WriteString("<![CDATA["); _Writer.WriteCData(GetNodeText(sourceNode, result)); _Writer.WriteString("]]>"); } else { _Writer.WriteCData(GetNodeText(sourceNode, result)); } _Writer.WriteEndElement(); } } else { _Writer.WriteStartElement(String.Empty, "Diff", String.Empty); _Writer.WriteAttributeString(String.Empty, "DiffType", String.Empty, GetDiffType(result)); if (sourceNode != null) { _Writer.WriteStartElement(String.Empty, "File1", String.Empty); if (sourceNode.NodeType == XmlDiffNodeType.CData) { _Writer.WriteString("<![CDATA["); _Writer.WriteCData(GetNodeText(sourceNode, result)); _Writer.WriteString("]]>"); } else { _Writer.WriteString(GetNodeText(sourceNode, result)); } _Writer.WriteEndElement(); } if (targetNode != null) { _Writer.WriteStartElement(String.Empty, "File2", String.Empty); if (targetNode.NodeType == XmlDiffNodeType.CData) { _Writer.WriteString("<![CDATA["); _Writer.WriteCData(GetNodeText(targetNode, result)); _Writer.WriteString("]]>"); } else { _Writer.WriteString(GetNodeText(targetNode, result)); } _Writer.WriteEndElement(); } _Writer.WriteEndElement(); _Writer.WriteStartElement(String.Empty, "Lexical-equal", String.Empty); _Writer.WriteEndElement(); } if (result != DiffType.Success || !DontWriteMatchingNodesToOutput) { _Writer.WriteEndElement(); } }
public XmlDiffNavigator(XmlDiffDocument doc) { _document = doc; _currentNode = _document; }
public override void MoveToRoot() { _currentNode = _document; }
private void LoadTextNode(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo, XmlDiffNodeType nt) { LoadTextNode(parent, reader.Value, pInfo, nt); }
// This function compares the two nodes passed to it, depending upon the options set by the user. private DiffType CompareNodes(XmlDiffNode sourceNode, XmlDiffNode targetNode) { if (sourceNode.NodeType != targetNode.NodeType) { return(DiffType.NodeType); } switch (sourceNode.NodeType) { case XmlDiffNodeType.Element: XmlDiffElement sourceElem = sourceNode as XmlDiffElement; XmlDiffElement targetElem = targetNode as XmlDiffElement; Debug.Assert(sourceElem != null); Debug.Assert(targetElem != null); if (!IgnoreNS) { if (sourceElem.NamespaceURI != targetElem.NamespaceURI) { return(DiffType.NS); } } if (!IgnorePrefix) { if (sourceElem.Prefix != targetElem.Prefix) { return(DiffType.Prefix); } } if (sourceElem.LocalName != targetElem.LocalName) { return(DiffType.Element); } if (!IgnoreEmptyElement) { if ((sourceElem is XmlDiffEmptyElement) != (targetElem is XmlDiffEmptyElement)) { return(DiffType.Element); } } if (!CompareAttributes(sourceElem, targetElem)) { return(DiffType.Attribute); } break; case XmlDiffNodeType.Text: case XmlDiffNodeType.Comment: case XmlDiffNodeType.WS: XmlDiffCharacterData sourceText = sourceNode as XmlDiffCharacterData; XmlDiffCharacterData targetText = targetNode as XmlDiffCharacterData; Debug.Assert(sourceText != null); Debug.Assert(targetText != null); if (ConcatenateAdjacentTextNodes) { DoConcatenateAdjacentTextNodes(sourceText); DoConcatenateAdjacentTextNodes(targetText); } if (IgnoreWhitespace) { if (sourceText.Value.Trim() == targetText.Value.Trim()) { return(DiffType.Success); } } else { if (sourceText.Value == targetText.Value) { return(DiffType.Success); } } if (sourceText.NodeType == XmlDiffNodeType.Text || sourceText.NodeType == XmlDiffNodeType.WS) //should ws nodes also as text nodes??? { return(DiffType.Text); } else if (sourceText.NodeType == XmlDiffNodeType.Comment) { return(DiffType.Comment); } else if (sourceText.NodeType == XmlDiffNodeType.CData) { return(DiffType.CData); } else { return(DiffType.None); } case XmlDiffNodeType.PI: XmlDiffProcessingInstruction sourcePI = sourceNode as XmlDiffProcessingInstruction; XmlDiffProcessingInstruction targetPI = targetNode as XmlDiffProcessingInstruction; Debug.Assert(sourcePI != null); Debug.Assert(targetPI != null); if (sourcePI.Name != targetPI.Name || sourcePI.Value != targetPI.Value) { return(DiffType.PI); } break; default: break; } return(DiffType.Success); }
internal void ReadChildNodes(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo) { bool lookAhead = false; do { lookAhead = false; switch (reader.NodeType) { case XmlNodeType.Element: LoadElement(parent, reader, pInfo); break; case XmlNodeType.Comment: if (!IgnoreComments) { LoadTextNode(parent, reader, pInfo, XmlDiffNodeType.Comment); } break; case XmlNodeType.ProcessingInstruction: LoadPI(parent, reader, pInfo); break; case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: if (!IgnoreWhitespace) { if (this.WhitespaceAsText) { LoadTextNode(parent, reader, pInfo, XmlDiffNodeType.Text); } else { LoadTextNode(parent, reader, pInfo, XmlDiffNodeType.WS); } } break; case XmlNodeType.CDATA: if (!CDataAsText) { LoadTextNode(parent, reader, pInfo, XmlDiffNodeType.CData); } else //merge with adjacent text/CDATA nodes { StringBuilder text = new StringBuilder(); text.Append(reader.Value); while ((lookAhead = reader.Read()) && (reader.NodeType == XmlNodeType.Text || reader.NodeType == XmlNodeType.CDATA)) { text.Append(reader.Value); } LoadTextNode(parent, text.ToString(), pInfo, XmlDiffNodeType.Text); } break; case XmlNodeType.Text: if (!CDataAsText) { LoadTextNode(parent, reader, pInfo, TextNodeIsWhitespace(reader.Value) ? XmlDiffNodeType.WS : XmlDiffNodeType.Text); } else //merge with adjacent text/CDATA nodes { StringBuilder text = new StringBuilder(); text.Append(reader.Value); while ((lookAhead = reader.Read()) && (reader.NodeType == XmlNodeType.Text || reader.NodeType == XmlNodeType.CDATA)) { text.Append(reader.Value); } string txt = text.ToString(); LoadTextNode(parent, txt, pInfo, TextNodeIsWhitespace(txt) ? XmlDiffNodeType.WS : XmlDiffNodeType.Text); } break; case XmlNodeType.EntityReference: LoadEntityReference(parent, reader, pInfo); break; case XmlNodeType.EndElement: SetElementEndPosition(parent as XmlDiffElement, pInfo); return; case XmlNodeType.Attribute: //attribute at top level string attrVal = reader.Name + "=\"" + reader.Value + "\""; LoadTopLevelAttribute(parent, attrVal, pInfo, XmlDiffNodeType.Text); break; default: break; } }while (lookAhead || reader.Read()); }