private void AnnotateNode(XmlDiffViewNode node, XmlDiffViewOperation op, int opid, bool bSubtree) { node._op = op; node._opid = opid; if (node._nodeType == XmlNodeType.Element) { XmlDiffViewAttribute attr = ((XmlDiffViewElement)node)._attributes; while (attr != null) { attr._op = op; attr._opid = opid; attr = (XmlDiffViewAttribute)attr._nextSibbling; } } if (bSubtree) { XmlDiffViewNode childNode = node.FirstChildNode; while (childNode != null) { AnnotateNode(childNode, op, opid, true); childNode = childNode._nextSibbling; } } }
static XmlDiffPathNodeList SelectAllChildren(XmlDiffViewParentNode parentNode) { if (parentNode._childNodes == null) { OnNoMatchingNode("*"); return(null); } else if (parentNode._childNodes._nextSibbling == null) { XmlDiffPathNodeList nodeList = new XmlDiffPathSingleNodeList(); nodeList.AddNode(parentNode._childNodes); return(nodeList); } else { XmlDiffPathNodeList nodeList = new XmlDiffPathMultiNodeList(); XmlDiffViewNode childNode = parentNode._childNodes; while (childNode != null) { nodeList.AddNode(childNode); childNode = childNode._nextSibbling; } return(nodeList); } }
private void AnnotateNode( XmlDiffViewNode node, XmlDiffViewOperation op, int opid, bool bSubtree) { node._op = op; node._opid = opid; if (node._nodeType == XmlNodeType.Element) { for (var diffViewAttribute = ((XmlDiffViewElement)node)._attributes; diffViewAttribute != null; diffViewAttribute = (XmlDiffViewAttribute)diffViewAttribute._nextSibbling) { diffViewAttribute._op = op; diffViewAttribute._opid = opid; } } if (!bSubtree) { return; } for (var node1 = node.FirstChildNode; node1 != null; node1 = node1._nextSibbling) { this.AnnotateNode(node1, op, opid, true); } }
/// <summary> /// Inserts a node after the specified node /// </summary> /// <param name="newChild">node to insert</param> /// <param name="referenceChild">node to insert after</param> /// <param name="sourceNode">This is a baseline node</param> internal void InsertChildAfter( XmlDiffViewNode newChild, XmlDiffViewNode referenceChild, bool sourceNode) { Debug.Assert(newChild != null); if (referenceChild == null) { // head of list. newChild.NextSibling = this.ChildNodes; if (this.ChildNodes != null) { this.ChildNodes.PreviousSibling = newChild; } this.ChildNodes = newChild; } else { newChild.NextSibling = referenceChild.NextSibling; newChild.PreviousSibling = referenceChild; if (referenceChild.NextSibling != null) { referenceChild.NextSibling.PreviousSibling = newChild; } referenceChild.NextSibling = newChild; } if (sourceNode) { this.SourceChildNodesCount++; } newChild.Parent = this; }
internal override void AddNode(XmlDiffViewNode node) { if (this._node != null) { throw new Exception("XmlDiffPathSingleNodeList can contain one node only."); } this._node = node; }
/// <summary> /// Gets a list of node objects corresponding to /// the proprietary path reference provided. /// </summary> /// <param name="rootNode">The starting node</param> /// <param name="path">Absolute path reference to node of interest</param> /// <returns>list of node objects</returns> private static XmlDiffPathNodeList SelectAbsoluteNodes( XmlDiffViewParentNode rootNode, string path) { Debug.Assert(path[0] == '/'); int pos = 1; XmlDiffViewNode node = rootNode; for (; ;) { int startPos = pos; int nodePos = ReadPosition(path, ref pos); if (pos == path.Length || path[pos] == '/') { if (node.FirstChildNode == null) { OnNoMatchingNode(path); } XmlDiffViewParentNode parentNode = (XmlDiffViewParentNode)node; if (nodePos <= 0 || nodePos > parentNode. SourceChildNodesCount) { OnNoMatchingNode(path); } node = parentNode.GetSourceChildNode(nodePos - 1); if (pos == path.Length) { XmlDiffPathNodeList list = new XmlDiffPathSingleNodeList(); list.AddNode(node); return(list); } pos++; } else { if (path[pos] == '-' || path[pos] == '|') { if (node.FirstChildNode == null) { OnNoMatchingNode(path); } return(SelectChildNodes( ((XmlDiffViewParentNode)node), path, startPos)); } OnInvalidExpression(path); } } }
private void OnRemove(XmlElement diffgramElement, XmlDiffPathNodeList matchNodes, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { // opid & descriptor XmlDiffViewOperation op = XmlDiffViewOperation.Remove; int opid = 0; OperationDescriptor opDesc = null; string opidAttr = diffgramElement.GetAttribute("opid"); if (opidAttr != string.Empty) { opid = int.Parse(opidAttr); opDesc = GetDescriptor(opid); if (opDesc._type == OperationDescriptor.Type.Move) { op = XmlDiffViewOperation.MoveFrom; } } // subtree string subtreeAttr = diffgramElement.GetAttribute("subtree"); bool bSubtree = (subtreeAttr != "no"); if (!bSubtree) { if (matchNodes.Count != 1) { throw new Exception("The 'match' attribute of 'remove' element must select a single node when the 'subtree' attribute is specified."); } // annotate node matchNodes.MoveNext(); XmlDiffViewNode node = matchNodes.Current; AnnotateNode(node, op, opid, false); if (opid != 0) { opDesc._nodeList.AddNode(node); } // recurse ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)node); } else { // annotate nodes matchNodes.Reset(); while (matchNodes.MoveNext()) { if (opid != 0) { opDesc._nodeList.AddNode(matchNodes.Current); } AnnotateNode(matchNodes.Current, op, opid, true); } } }
internal void HtmlDrawChildNodes(XmlWriter writer, int indent) { XmlDiffViewNode curChild = _childNodes; while (curChild != null) { curChild.DrawHtml(writer, indent); curChild = curChild._nextSibbling; } }
private void OnAddMatch(XmlElement diffgramElement, XmlDiffPathNodeList matchNodes, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { string opidAttr = diffgramElement.GetAttribute("opid"); if (opidAttr == string.Empty) { throw new Exception("Missing opid attribute."); } // opid & descriptor int opid = int.Parse(opidAttr); OperationDescriptor opDesc = GetDescriptor(opid); string subtreeAttr = diffgramElement.GetAttribute("subtree"); bool bSubtree = (subtreeAttr != "no"); // move single node without subtree if (!bSubtree) { if (matchNodes.Count != 1) { throw new Exception("The 'match' attribute of 'add' element must select a single node when the 'subtree' attribute is specified."); } // clone node matchNodes.MoveNext(); XmlDiffViewNode newNode = matchNodes.Current.Clone(false); AnnotateNode(newNode, XmlDiffViewOperation.MoveTo, opid, true); opDesc._nodeList.AddNode(newNode); // insert in tree sourceParent.InsertChildAfter(newNode, currentPosition, false); currentPosition = newNode; // recurse ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)newNode); } // move subtree else { matchNodes.Reset(); while (matchNodes.MoveNext()) { XmlDiffViewNode newNode = matchNodes.Current.Clone(true); AnnotateNode(newNode, XmlDiffViewOperation.MoveTo, opid, true); opDesc._nodeList.AddNode(newNode); sourceParent.InsertChildAfter(newNode, currentPosition, false); currentPosition = newNode; } } }
private XmlDiffViewNode ImportNode(XmlNode node) { XmlDiffViewNode newNode = null; switch (node.NodeType) { case XmlNodeType.Element: XmlElement el = (XmlElement)node; XmlDiffViewElement newElement = new XmlDiffViewElement(el.LocalName, el.Prefix, el.NamespaceURI, _bIgnorePrefixes); // attributes IEnumerator attributes = node.Attributes.GetEnumerator(); XmlDiffViewAttribute lastNewAttr = null; while (attributes.MoveNext()) { XmlAttribute at = (XmlAttribute)attributes.Current; XmlDiffViewAttribute newAttr = new XmlDiffViewAttribute(at.LocalName, at.Prefix, at.NamespaceURI, at.Value); newElement.InsertAttributeAfter(newAttr, lastNewAttr); lastNewAttr = newAttr; } // children IEnumerator childNodes = node.ChildNodes.GetEnumerator(); XmlDiffViewNode lastNewChildNode = null; while (childNodes.MoveNext()) { XmlDiffViewNode newChildNode = ImportNode((XmlNode)childNodes.Current); newElement.InsertChildAfter(newChildNode, lastNewChildNode, false); lastNewChildNode = newChildNode; } newNode = newElement; break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Comment: newNode = new XmlDiffViewCharData(node.Value, node.NodeType); break; case XmlNodeType.ProcessingInstruction: newNode = new XmlDiffViewPI(node.Name, node.Value); break; case XmlNodeType.EntityReference: newNode = new XmlDiffViewER(node.Name); break; default: Debug.Assert(false, "Invalid node type."); break; } Debug.Assert(newNode != null); return(newNode); }
private void OnAddFragment(XmlElement diffgramElement, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { IEnumerator childNodes = diffgramElement.ChildNodes.GetEnumerator(); while (childNodes.MoveNext()) { XmlDiffViewNode newChildNode = ImportNode((XmlNode)childNodes.Current); sourceParent.InsertChildAfter(newChildNode, currentPosition, false); currentPosition = newChildNode; AnnotateNode(newChildNode, XmlDiffViewOperation.Add, 0, true); } }
private void OnAddFragment( XmlElement diffgramElement, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { foreach (XmlNode childNode in diffgramElement.ChildNodes) { var xmlDiffViewNode = this.ImportNode(childNode); sourceParent.InsertChildAfter(xmlDiffViewNode, currentPosition, false); currentPosition = xmlDiffViewNode; this.AnnotateNode(xmlDiffViewNode, XmlDiffViewOperation.Add, 0, true); } }
/// <summary> /// Generates output data in text form /// </summary> /// <param name="writer">output stream</param> /// <param name="indent">number of indentations</param> internal void TextDrawChildNodes( TextWriter writer, int indent) { indent += Indent.IncrementSize; XmlDiffViewNode curChild = this.ChildNodes; while (curChild != null) { curChild.DrawText(writer, indent); curChild = curChild.NextSibbling; } }
private XmlDiffViewNode ImportNode(XmlNode node) { XmlDiffViewNode xmlDiffViewNode = null; switch (node.NodeType) { case XmlNodeType.Element: var xmlElement = (XmlElement)node; var xmlDiffViewElement = new XmlDiffViewElement(xmlElement.LocalName, xmlElement.Prefix, xmlElement.NamespaceURI, this._bIgnorePrefixes); var enumerator1 = node.Attributes.GetEnumerator(); XmlDiffViewAttribute refAttr = null; while (enumerator1.MoveNext()) { var current = (XmlAttribute)enumerator1.Current; var newAttr = new XmlDiffViewAttribute(current.LocalName, current.Prefix, current.NamespaceURI, current.Value); xmlDiffViewElement.InsertAttributeAfter(newAttr, refAttr); refAttr = newAttr; } var enumerator2 = node.ChildNodes.GetEnumerator(); XmlDiffViewNode referenceChild = null; while (enumerator2.MoveNext()) { var newChild = this.ImportNode((XmlNode)enumerator2.Current); xmlDiffViewElement.InsertChildAfter(newChild, referenceChild, false); referenceChild = newChild; } xmlDiffViewNode = xmlDiffViewElement; break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Comment: xmlDiffViewNode = new XmlDiffViewCharData(node.Value, node.NodeType); break; case XmlNodeType.EntityReference: xmlDiffViewNode = new XmlDiffViewER(node.Name); break; case XmlNodeType.ProcessingInstruction: xmlDiffViewNode = new XmlDiffViewPI(node.Name, node.Value); break; default: Debug.Assert(false, "Invalid node type."); break; } Debug.Assert(xmlDiffViewNode != null); return(xmlDiffViewNode); }
private void OnRemove( XmlElement diffgramElement, XmlDiffPathNodeList matchNodes, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { var op = XmlDiffViewOperation.Remove; var opid = 0; OperationDescriptor operationDescriptor = null; var attribute = diffgramElement.GetAttribute("opid"); if (attribute != string.Empty) { opid = int.Parse(attribute); operationDescriptor = this.GetDescriptor(opid); if (operationDescriptor._type == OperationDescriptor.Type.Move) { op = XmlDiffViewOperation.MoveFrom; } } if (!(diffgramElement.GetAttribute("subtree") != "no")) { if (matchNodes.Count != 1) { throw new Exception("The 'match' attribute of 'remove' element must select a single node when the 'subtree' attribute is specified."); } matchNodes.MoveNext(); var current = matchNodes.Current; this.AnnotateNode(current, op, opid, false); if (opid != 0) { operationDescriptor._nodeList.AddNode(current); } this.ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)current); } else { matchNodes.Reset(); while (matchNodes.MoveNext()) { if (opid != 0) { operationDescriptor._nodeList.AddNode(matchNodes.Current); } this.AnnotateNode(matchNodes.Current, op, opid, true); } } }
internal override void AddNode(XmlDiffViewNode node) { if (this._lastChunk == null) { this._chunks = new ListChunk(); this._lastChunk = this._chunks; this._currentChunk = this._chunks; } else if (this._lastChunk._count == 10) { this._lastChunk._next = new ListChunk(); this._lastChunk = this._lastChunk._next; } this._lastChunk.AddNode(node); ++this._count; }
/// <summary> /// Adds a node to the current list of data. /// </summary> /// <param name="node">Node object to add</param> public override void AddNode(XmlDiffViewNode node) { if (this.lastChunk == null) { this.chunks = new ListChunk(); this.lastChunk = this.chunks; this.currentChunk = this.chunks; } else if (this.lastChunk.Count == ListChunk.ChunkSize) { this.lastChunk.Next = new ListChunk(); this.lastChunk = this.lastChunk.Next; } this.lastChunk.AddNode(node); this.count++; }
internal override void AddNode(XmlDiffViewNode node) { if (_lastChunk == null) { _chunks = new ListChunk(); _lastChunk = _chunks; _currentChunk = _chunks; } else if (_lastChunk._count == ListChunk.ChunkSize) { _lastChunk._next = new ListChunk(); _lastChunk = _lastChunk._next; } _lastChunk.AddNode(node); _count++; }
internal void CreateSourceNodesIndex() { if (_sourceChildNodesIndex != null || _sourceChildNodesCount == 0) { return; } _sourceChildNodesIndex = new XmlDiffViewNode[_sourceChildNodesCount]; XmlDiffViewNode curChild = _childNodes; for (int i = 0; i < _sourceChildNodesCount; i++, curChild = curChild._nextSibbling) { Debug.Assert(curChild != null); _sourceChildNodesIndex[i] = curChild; } Debug.Assert(curChild == null); }
/// <summary> /// Creates a complete copy of the current node. /// </summary> /// <param name="deep">has child nodes</param> /// <returns>A copy of the current node</returns> internal override XmlDiffViewNode Clone(bool deep) { XmlDiffViewElement newElement = new XmlDiffViewElement( this.LocalName, this.Prefix, this.NamespaceUri, this.ignorePrefixes); // attributes { XmlDiffViewAttribute curAttr = this.Attributes; XmlDiffViewAttribute lastNewAtt = null; while (curAttr != null) { XmlDiffViewAttribute newAttr = (XmlDiffViewAttribute)curAttr.Clone(true); newElement.InsertAttributeAfter(newAttr, lastNewAtt); lastNewAtt = newAttr; curAttr = (XmlDiffViewAttribute)curAttr.NextSibbling; } } if (!deep) { return(newElement); } // child nodes { XmlDiffViewNode curChild = ChildNodes; XmlDiffViewNode lastNewChild = null; while (curChild != null) { XmlDiffViewNode newChild = curChild.Clone(true); newElement.InsertChildAfter(newChild, lastNewChild, false); lastNewChild = newChild; curChild = curChild.NextSibbling; } } return(newElement); }
/// <summary> /// Creates an indexed collection of child nodes. /// </summary> internal void CreateSourceNodesIndex() { if (this.SourceChildNodesIndex != null || this.SourceChildNodesCount == 0) { return; } this.SourceChildNodesIndex = new XmlDiffViewNode[this.SourceChildNodesCount]; XmlDiffViewNode curChild = this.ChildNodes; for (int i = 0; i < this.SourceChildNodesCount; i++, curChild = curChild.NextSibbling) { Debug.Assert(curChild != null); this.SourceChildNodesIndex[i] = curChild; } Debug.Assert(curChild == null); }
internal void InsertChildAfter(XmlDiffViewNode newChild, XmlDiffViewNode referenceChild, bool bSourceNode) { Debug.Assert(newChild != null); if (referenceChild == null) { newChild._nextSibbling = _childNodes; _childNodes = newChild; } else { newChild._nextSibbling = referenceChild._nextSibbling; referenceChild._nextSibbling = newChild; } if (bSourceNode) { _sourceChildNodesCount++; } newChild._parent = this; }
private void OnAddMatch( XmlElement diffgramElement, XmlDiffPathNodeList matchNodes, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { var attribute = diffgramElement.GetAttribute("opid"); if (attribute == string.Empty) { throw new Exception("Missing opid attribute."); } var opid = int.Parse(attribute); var descriptor = this.GetDescriptor(opid); if (!(diffgramElement.GetAttribute("subtree") != "no")) { if (matchNodes.Count != 1) { throw new Exception("The 'match' attribute of 'add' element must select a single node when the 'subtree' attribute is specified."); } matchNodes.MoveNext(); var xmlDiffViewNode = matchNodes.Current.Clone(false); this.AnnotateNode(xmlDiffViewNode, XmlDiffViewOperation.MoveTo, opid, true); descriptor._nodeList.AddNode(xmlDiffViewNode); sourceParent.InsertChildAfter(xmlDiffViewNode, currentPosition, false); currentPosition = xmlDiffViewNode; this.ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)xmlDiffViewNode); } else { matchNodes.Reset(); while (matchNodes.MoveNext()) { var xmlDiffViewNode = matchNodes.Current.Clone(true); this.AnnotateNode(xmlDiffViewNode, XmlDiffViewOperation.MoveTo, opid, true); descriptor._nodeList.AddNode(xmlDiffViewNode); sourceParent.InsertChildAfter(xmlDiffViewNode, currentPosition, false); currentPosition = xmlDiffViewNode; } } }
/// <summary> /// Inserts a node after the specified node /// </summary> /// <param name="newChild">node to insert</param> /// <param name="referenceChild">node to insert after</param> /// <param name="sourceNode">This is a baseline node</param> internal void InsertChildAfter( XmlDiffViewNode newChild, XmlDiffViewNode referenceChild, bool sourceNode) { Debug.Assert(newChild != null); if (referenceChild == null) { newChild.NextSibbling = this.ChildNodes; this.ChildNodes = newChild; } else { newChild.NextSibbling = referenceChild.NextSibbling; referenceChild.NextSibbling = newChild; } if (sourceNode) { this.SourceChildNodesCount++; } newChild.Parent = this; }
internal override XmlDiffViewNode Clone(bool bDeep) { XmlDiffViewElement newElement = new XmlDiffViewElement(_localName, _prefix, _ns, _ignorePrefixes); // attributes { XmlDiffViewAttribute curAttr = _attributes; XmlDiffViewAttribute lastNewAtt = null; while (curAttr != null) { XmlDiffViewAttribute newAttr = (XmlDiffViewAttribute)curAttr.Clone(true); newElement.InsertAttributeAfter(newAttr, lastNewAtt); lastNewAtt = newAttr; curAttr = (XmlDiffViewAttribute)curAttr._nextSibbling; } } if (!bDeep) { return(newElement); } // child nodes { XmlDiffViewNode curChild = _childNodes; XmlDiffViewNode lastNewChild = null; while (curChild != null) { XmlDiffViewNode newChild = curChild.Clone(true); newElement.InsertChildAfter(newChild, lastNewChild, false); lastNewChild = newChild; curChild = curChild._nextSibbling; } } return(newElement); }
private void OnAddNode( XmlElement diffgramElement, string nodeTypeAttr, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { var nodeType = (XmlNodeType)int.Parse(nodeTypeAttr); var attribute1 = diffgramElement.GetAttribute("name"); var attribute2 = diffgramElement.GetAttribute("prefix"); var attribute3 = diffgramElement.GetAttribute("ns"); var attribute4 = diffgramElement.GetAttribute("opid"); var num = attribute4 == string.Empty ? 0 : int.Parse(attribute4); if (nodeType == XmlNodeType.Attribute) { Debug.Assert(attribute1 != string.Empty); var newAttr = new XmlDiffViewAttribute(attribute1, attribute2, attribute3, diffgramElement.InnerText); newAttr._op = XmlDiffViewOperation.Add; newAttr._opid = num; ((XmlDiffViewElement)sourceParent).InsertAttributeAfter(newAttr, null); } else { XmlDiffViewNode newChild = null; switch (nodeType) { case XmlNodeType.Element: Debug.Assert(attribute1 != string.Empty); newChild = new XmlDiffViewElement(attribute1, attribute2, attribute3, this._bIgnorePrefixes); this.ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)newChild); break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Comment: Debug.Assert(diffgramElement.InnerText != string.Empty); newChild = new XmlDiffViewCharData(diffgramElement.InnerText, nodeType); break; case XmlNodeType.EntityReference: Debug.Assert(attribute1 != string.Empty); newChild = new XmlDiffViewER(attribute1); break; case XmlNodeType.ProcessingInstruction: Debug.Assert(diffgramElement.InnerText != string.Empty); Debug.Assert(attribute1 != string.Empty); newChild = new XmlDiffViewPI(attribute1, diffgramElement.InnerText); break; case XmlNodeType.DocumentType: newChild = new XmlDiffViewDocumentType(diffgramElement.GetAttribute("name"), diffgramElement.GetAttribute("publicId"), diffgramElement.GetAttribute("systemId"), diffgramElement.InnerText); break; case XmlNodeType.XmlDeclaration: Debug.Assert(diffgramElement.InnerText != string.Empty); newChild = new XmlDiffViewXmlDeclaration(diffgramElement.InnerText); break; default: Debug.Assert(false, "Invalid node type."); break; } Debug.Assert(newChild != null); newChild._op = XmlDiffViewOperation.Add; newChild._opid = num; sourceParent.InsertChildAfter(newChild, currentPosition, false); currentPosition = newChild; } }
/// <summary> /// Add a node to the list. This method should only be /// called once otherwise an exception will be raised. /// </summary> /// <param name="node">The node to add</param> public override void AddNode(XmlDiffViewNode node) { if (this.node != null) { throw new Exception( "XmlDiffPathSingleNodeList can contain one node only."); } this.node = node; }
internal override void AddNode( XmlDiffViewNode node ) { if ( _node != null ) throw new Exception( "XmlDiffPathSingleNodeList can contain one node only." ); _node = node; }
/// <summary> /// Mark the nodes (and attributes) with the type of data change /// </summary> /// <param name="node">the node to annotate</param> /// <param name="op">the type of data change</param> /// <param name="opid">the operation identification number</param> /// <param name="subtree">the node's subtree</param> private void AnnotateNode( XmlDiffViewNode node, XmlDiffViewOperation op, int opid, bool subtree) { node.Operation = op; node.OperationId = opid; if (node.NodeType == XmlNodeType.Element) { XmlDiffViewAttribute attr = ( (XmlDiffViewElement)node).Attributes; while (attr != null) { attr.Operation = op; attr.OperationId = opid; attr = (XmlDiffViewAttribute)attr.NextSibbling; } } if (subtree) { XmlDiffViewNode childNode = node.FirstChildNode; while (childNode != null) { this.AnnotateNode(childNode, op, opid, true); childNode = childNode.NextSibbling; } } }
private void ApplyDiffgram(XmlNode diffgramParent, XmlDiffViewParentNode sourceParent) { sourceParent.CreateSourceNodesIndex(); XmlDiffViewNode currentPosition = null; var enumerator = diffgramParent.ChildNodes.GetEnumerator(); while (enumerator.MoveNext()) { if (((XmlNode)enumerator.Current).NodeType != XmlNodeType.Comment) { if (!(enumerator.Current is XmlElement)) { throw new Exception("Invalid node in diffgram."); } var current = enumerator.Current as XmlElement; if (current.NamespaceURI != "http://schemas.microsoft.com/xmltools/2002/xmldiff") { throw new Exception("Invalid element in diffgram."); } var attribute1 = current.GetAttribute("match"); XmlDiffPathNodeList matchNodes = null; if (attribute1 != string.Empty) { matchNodes = XmlDiffPath.SelectNodes(this._doc, sourceParent, attribute1); } switch (current.LocalName) { case "node": if (matchNodes.Count != 1) { throw new Exception("The 'match' attribute of 'node' element must select a single node."); } matchNodes.MoveNext(); if (current.ChildNodes.Count > 0) { this.ApplyDiffgram(current, (XmlDiffViewParentNode)matchNodes.Current); } currentPosition = matchNodes.Current; continue; case "add": if (attribute1 != string.Empty) { this.OnAddMatch(current, matchNodes, sourceParent, ref currentPosition); continue; } var attribute2 = current.GetAttribute("type"); if (attribute2 != string.Empty) { this.OnAddNode(current, attribute2, sourceParent, ref currentPosition); continue; } this.OnAddFragment(current, sourceParent, ref currentPosition); continue; case "remove": this.OnRemove(current, matchNodes, sourceParent, ref currentPosition); continue; case "change": this.OnChange(current, matchNodes, sourceParent, ref currentPosition); continue; default: continue; } } } }
private void OnChange( XmlElement diffgramElement, XmlDiffPathNodeList matchNodes, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { Debug.Assert(matchNodes.Count == 1); matchNodes.Reset(); matchNodes.MoveNext(); var current = matchNodes.Current; if (current._nodeType != XmlNodeType.Attribute) { currentPosition = current; } var changeInfo = new XmlDiffViewNode.ChangeInfo(); var str1 = diffgramElement.HasAttribute("name") ? diffgramElement.GetAttribute("name") : null; var str2 = diffgramElement.HasAttribute("prefix") ? diffgramElement.GetAttribute("prefix") : null; var str3 = diffgramElement.HasAttribute("ns") ? diffgramElement.GetAttribute("ns") : null; switch (current._nodeType) { case XmlNodeType.Element: changeInfo._localName = str1 == null ? ((XmlDiffViewElement)current)._localName : str1; changeInfo._prefix = str2 == null ? ((XmlDiffViewElement)current)._prefix : str2; changeInfo._ns = str3 == null ? ((XmlDiffViewElement)current)._ns : str3; break; case XmlNodeType.Attribute: var innerText = diffgramElement.InnerText; if (str1 == string.Empty && str2 == string.Empty && innerText == string.Empty) { return; } changeInfo._localName = str1 == null ? ((XmlDiffViewAttribute)current)._localName : str1; changeInfo._prefix = str2 == null ? ((XmlDiffViewAttribute)current)._prefix : str2; changeInfo._ns = str3 == null ? ((XmlDiffViewAttribute)current)._ns : str3; changeInfo._value = diffgramElement.InnerText; break; case XmlNodeType.Text: case XmlNodeType.CDATA: Debug.Assert(diffgramElement.FirstChild != null); changeInfo._value = diffgramElement.InnerText; break; case XmlNodeType.EntityReference: Debug.Assert(str1 != null); changeInfo._localName = str1; break; case XmlNodeType.ProcessingInstruction: if (str1 == null) { Debug.Assert(diffgramElement.FirstChild != null); Debug.Assert(diffgramElement.FirstChild.NodeType == XmlNodeType.ProcessingInstruction); changeInfo._localName = diffgramElement.FirstChild.Name; changeInfo._value = diffgramElement.FirstChild.Value; break; } changeInfo._localName = str1; changeInfo._value = ((XmlDiffViewCharData)current)._value; break; case XmlNodeType.Comment: Debug.Assert(diffgramElement.FirstChild != null); Debug.Assert(diffgramElement.FirstChild.NodeType == XmlNodeType.Comment); changeInfo._value = diffgramElement.FirstChild.Value; break; case XmlNodeType.DocumentType: changeInfo._localName = str1 == null ? ((XmlDiffViewDocumentType)current)._name : str1; changeInfo._prefix = !diffgramElement.HasAttribute("publicId") ? ((XmlDiffViewDocumentType)current)._publicId : diffgramElement.GetAttribute("publicId"); changeInfo._ns = !diffgramElement.HasAttribute("systemId") ? ((XmlDiffViewDocumentType)current)._systemId : diffgramElement.GetAttribute("systemId"); changeInfo._value = diffgramElement.FirstChild == null ? ((XmlDiffViewDocumentType)current)._subset : diffgramElement.InnerText; break; case XmlNodeType.XmlDeclaration: Debug.Assert(diffgramElement.FirstChild != null); changeInfo._value = diffgramElement.InnerText; break; default: Debug.Assert(false, "Invalid node type."); break; } current._changeInfo = changeInfo; current._op = XmlDiffViewOperation.Change; var attribute = diffgramElement.GetAttribute("opid"); if (attribute != string.Empty) { current._opid = int.Parse(attribute); } if (current._nodeType != XmlNodeType.Element || diffgramElement.FirstChild == null) { return; } this.ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)current); }
public void Reset() { this._curLastChild = null; this._curLastAttribute = null; }
/// <summary> /// Relocate matched data. /// </summary> /// <param name="diffgramElement">node in diffgram</param> /// <param name="matchNodes">the path to the baseline node</param> /// <param name="sourceParent">the baseline parent node</param> /// <param name="currentPosition">the resulting node</param> private void OnAddMatch( XmlElement diffgramElement, XmlDiffPathNodeList matchNodes, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { string opidAttr = diffgramElement.GetAttribute("opid"); if (opidAttr == string.Empty) { throw new Exception("Missing opid attribute."); } // opid & descriptor int opid = ParseOpId(opidAttr); OperationDescriptor operationDesc = this.GetDescriptor(opid); string subtreeAttr = diffgramElement.GetAttribute("subtree"); bool subtree = (subtreeAttr != "no"); // move single node without subtree if (!subtree) { if (matchNodes.Count != 1) { throw new Exception("The 'match' attribute of 'add' " + "element must select a single node when the 'subtree' " + "attribute is specified."); } // clone node matchNodes.MoveNext(); XmlDiffViewNode newNode = matchNodes.Current.Clone(false); this.AnnotateNode( newNode, XmlDiffViewOperation.MoveTo, opid, true); operationDesc.NodeList.AddNode(newNode); // insert in tree sourceParent.InsertChildAfter(newNode, currentPosition, false); currentPosition = newNode; // recurse this.ApplyDiffgram( diffgramElement, (XmlDiffViewParentNode)newNode); } else { // move subtree matchNodes.Reset(); while (matchNodes.MoveNext()) { XmlDiffViewNode newNode = matchNodes.Current.Clone(true); this.AnnotateNode( newNode, XmlDiffViewOperation.MoveTo, opid, true); operationDesc.NodeList.AddNode(newNode); sourceParent.InsertChildAfter(newNode, currentPosition, false); currentPosition = newNode; } } }
/// <summary> /// Add the new fragment /// </summary> /// <param name="diffgramElement">node in diffgram</param> /// <param name="sourceParent">the baseline parent node</param> /// <param name="currentPosition">the resulting node</param> private void OnAddFragment( XmlElement diffgramElement, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { int opid = NextOperationId; IEnumerator childNodes = diffgramElement.ChildNodes.GetEnumerator(); while (childNodes.MoveNext()) { XmlDiffViewNode newChildNode = this.ImportNode( (XmlNode)childNodes.Current); sourceParent.InsertChildAfter( newChildNode, currentPosition, false); currentPosition = newChildNode; this.AnnotateNode( newChildNode, XmlDiffViewOperation.Add, opid, true); } }
/// <summary> /// Add the new node or attribute /// </summary> /// <param name="diffgramElement">node in diffgram</param> /// <param name="nodeTypeAttr">Whether this is an Attribute</param> /// <param name="sourceParent">the baseline parent node</param> /// <param name="currentPosition">the resulting node</param> private void OnAddNode( XmlElement diffgramElement, string nodeTypeAttr, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { XmlNodeType nodeType = (XmlNodeType) int.Parse(nodeTypeAttr); string name = diffgramElement.GetAttribute("name"); string prefix = diffgramElement.GetAttribute("prefix"); string ns = diffgramElement.GetAttribute("ns"); string opidAttr = diffgramElement.GetAttribute("opid"); int opid = ParseOpId(opidAttr); if (nodeType == XmlNodeType.Attribute) { Debug.Assert(name != string.Empty); XmlDiffViewAttribute newAttr = new XmlDiffViewAttribute( name, prefix, ns, diffgramElement.InnerText); newAttr.Operation = XmlDiffViewOperation.Add; newAttr.OperationId = opid; ((XmlDiffViewElement) sourceParent).InsertAttributeAfter(newAttr, null); } else { XmlDiffViewNode newNode = null; switch (nodeType) { case XmlNodeType.Element: Debug.Assert(name != string.Empty); newNode = new XmlDiffViewElement( name, prefix, ns, this.ignorePrefixes); this.ApplyDiffgram( diffgramElement, (XmlDiffViewParentNode)newNode); break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Comment: Debug.Assert(diffgramElement.InnerText != string.Empty); newNode = new XmlDiffViewCharData( diffgramElement.InnerText, nodeType); break; case XmlNodeType.ProcessingInstruction: Debug.Assert(diffgramElement.InnerText != string.Empty); Debug.Assert(name != string.Empty); newNode = new XmlDiffViewPI( name, diffgramElement.InnerText); break; case XmlNodeType.EntityReference: Debug.Assert(name != string.Empty); Debug.Assert(false, "XmlDiffViewER was thought to be dead code"); //// newNode = new XmlDiffViewER(name); break; case XmlNodeType.XmlDeclaration: Debug.Assert(diffgramElement.InnerText != string.Empty); newNode = new XmlDiffViewXmlDeclaration( diffgramElement.InnerText); break; case XmlNodeType.DocumentType: newNode = new XmlDiffViewDocumentType( diffgramElement.GetAttribute("name"), diffgramElement.GetAttribute("publicId"), diffgramElement.GetAttribute("systemId"), diffgramElement.InnerText); break; default: Debug.Assert(false, "Invalid node type."); break; } Debug.Assert(newNode != null); newNode.Operation = XmlDiffViewOperation.Add; newNode.OperationId = opid; sourceParent.InsertChildAfter(newNode, currentPosition, false); currentPosition = newNode; } }
/// <summary> /// Store changes in the ChangeInfo object of the marked-up-baseline node /// </summary> /// <param name="diffgramElement">current element in the diffgram</param> /// <param name="matchNodes">Object containing the list of baseline nodes /// which match the position in the diffgram</param> /// <param name="sourceParent">parent node in the baseline data</param> /// <param name="currentPosition">current position</param> private void OnChange( XmlElement diffgramElement, XmlDiffPathNodeList matchNodes, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { Debug.Assert(matchNodes.Count == 1); matchNodes.Reset(); matchNodes.MoveNext(); XmlDiffViewNode node = matchNodes.Current; if (node.NodeType != XmlNodeType.Attribute) { currentPosition = node; } XmlDiffViewNode.ChangeInfo changeInfo = new XmlDiffViewNode.ChangeInfo(); string name = diffgramElement.HasAttribute("name") ? diffgramElement.GetAttribute("name") : null; string prefix = diffgramElement.HasAttribute("prefix") ? diffgramElement.GetAttribute("prefix") : null; string ns = diffgramElement.HasAttribute("ns") ? diffgramElement.GetAttribute("ns") : null; switch (node.NodeType) { case XmlNodeType.Element: changeInfo.LocalName = (name == null) ? ((XmlDiffViewElement)node).LocalName : name; changeInfo.Prefix = (prefix == null) ? ((XmlDiffViewElement)node).Prefix : prefix; changeInfo.NamespaceUri = (ns == null) ? ((XmlDiffViewElement)node).NamespaceUri : ns; break; case XmlNodeType.Attribute: string value = diffgramElement.InnerText; if (name == string.Empty && prefix == string.Empty && value == string.Empty) { return; } changeInfo.LocalName = (name == null) ? ((XmlDiffViewAttribute)node).LocalName : name; changeInfo.Prefix = (prefix == null) ? ((XmlDiffViewAttribute)node).Prefix : prefix; changeInfo.NamespaceUri = (ns == null) ? ((XmlDiffViewAttribute)node).NamespaceUri : ns; changeInfo.Subset = diffgramElement.InnerText; break; case XmlNodeType.Text: case XmlNodeType.CDATA: Debug.Assert(diffgramElement.FirstChild != null); changeInfo.Subset = diffgramElement.InnerText; break; case XmlNodeType.Comment: Debug.Assert(diffgramElement.FirstChild != null); Debug.Assert(diffgramElement.FirstChild.NodeType == XmlNodeType.Comment); changeInfo.Subset = diffgramElement.FirstChild.Value; break; case XmlNodeType.ProcessingInstruction: if (name == null) { Debug.Assert(diffgramElement.FirstChild != null); Debug.Assert(diffgramElement.FirstChild.NodeType == XmlNodeType.ProcessingInstruction); changeInfo.LocalName = diffgramElement.FirstChild.Name; changeInfo.Subset = diffgramElement.FirstChild.Value; } else { changeInfo.LocalName = name; changeInfo.Subset = ((XmlDiffViewPI)node).InnerText; } break; case XmlNodeType.EntityReference: Debug.Assert(name != null); changeInfo.LocalName = name; break; case XmlNodeType.XmlDeclaration: Debug.Assert(diffgramElement.FirstChild != null); changeInfo.Subset = diffgramElement.InnerText; break; case XmlNodeType.DocumentType: changeInfo.LocalName = (name == null) ? ((XmlDiffViewDocumentType)node).Name : name; if (diffgramElement.HasAttribute("publicId")) { changeInfo.Prefix = diffgramElement.GetAttribute("publicId"); } else { changeInfo.Prefix = ((XmlDiffViewDocumentType)node).PublicId; } if (diffgramElement.HasAttribute("systemId")) { changeInfo.NamespaceUri = diffgramElement.GetAttribute("systemId"); } else { changeInfo.NamespaceUri = ((XmlDiffViewDocumentType)node).SystemId; } if (diffgramElement.FirstChild != null) { changeInfo.Subset = diffgramElement.InnerText; } else { changeInfo.Subset = ((XmlDiffViewDocumentType)node).Subset; } break; default: Debug.Assert(false, "Invalid node type."); break; } node.ChangeInformation = changeInfo; node.Operation = XmlDiffViewOperation.Change; string opidAttr = diffgramElement.GetAttribute("opid"); if (opidAttr != string.Empty) { node.OperationId = int.Parse(opidAttr); } else { node.OperationId = NextOperationId; } if (node.NodeType == XmlNodeType.Element && diffgramElement.FirstChild != null) { this.ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)node); } }
/// <summary> /// Tag the relocated data /// </summary> /// <param name="diffgramElement">node in diffgram</param> /// <param name="matchNodes">the path to the baseline node</param> /// <param name="sourceParent">the baseline parent node</param> /// <param name="currentPosition">the resulting node</param> private void OnRemove( XmlElement diffgramElement, XmlDiffPathNodeList matchNodes, XmlDiffViewParentNode sourceParent, ref XmlDiffViewNode currentPosition) { // opid & descriptor XmlDiffViewOperation operation = XmlDiffViewOperation.Remove; int operationId = 0; OperationDescriptor operationDesc = null; string opidAttr = diffgramElement.GetAttribute("opid"); if (opidAttr != string.Empty) { operationId = int.Parse(opidAttr); operationDesc = this.GetDescriptor(operationId); if (operationDesc.OperationType == OperationDescriptor.Type.Move) { operation = XmlDiffViewOperation.MoveFrom; } } else { operationId = NextOperationId; } // subtree string subtreeAttr = diffgramElement.GetAttribute("subtree"); bool subtree = (subtreeAttr != "no"); if (!subtree) { if (matchNodes.Count != 1) { throw new Exception("The 'match' attribute of 'remove' " + "element must select a single node when the 'subtree' " + "attribute is specified."); } // annotate node matchNodes.MoveNext(); XmlDiffViewNode node = matchNodes.Current; this.AnnotateNode(node, operation, operationId, false); if (operationId != 0 && operationDesc != null) { operationDesc.NodeList.AddNode(node); } // recurse this.ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)node); } else { // annotate nodes matchNodes.Reset(); while (matchNodes.MoveNext()) { if (operationId != 0 && operationDesc != null) { operationDesc.NodeList.AddNode(matchNodes.Current); } this.AnnotateNode(matchNodes.Current, operation, operationId, true); } } }
/// <summary> /// Clear the references the last /// child node and attribute processed. /// </summary> public void Reset() { this.lastChild = null; this.lastAttribute = null; }
internal abstract void AddNode( XmlDiffViewNode node );
/// <summary> /// Add a node to the current list of data. /// </summary> /// <param name="node">Node object to add</param> public abstract void AddNode(XmlDiffViewNode node);
internal void AddNode( XmlDiffViewNode node ) { Debug.Assert( _count < ChunkSize ); _nodes[ _count++ ] = node; }
internal void InsertChildAfter( XmlDiffViewNode newChild, XmlDiffViewNode referenceChild, bool bSourceNode ) { Debug.Assert( newChild != null ); if ( referenceChild == null ) { newChild._nextSibbling = _childNodes; _childNodes = newChild; } else { newChild._nextSibbling = referenceChild._nextSibbling; referenceChild._nextSibbling = newChild; } if ( bSourceNode ) _sourceChildNodesCount++; newChild._parent = this; }
internal override void AddNode( XmlDiffViewNode node ) { if ( _lastChunk == null ) { _chunks = new ListChunk(); _lastChunk = _chunks; _currentChunk = _chunks; } else if ( _lastChunk._count == ListChunk.ChunkSize ) { _lastChunk._next = new ListChunk(); _lastChunk = _lastChunk._next; } _lastChunk.AddNode( node ); _count++; }
private void LoadSourceChildNodes( XmlDiffViewParentNode parent, XmlReader reader, bool bEmptyElement) { var loadState = this._loadState; this._loadState.Reset(); while (reader.MoveToNextAttribute()) { XmlDiffViewAttribute newAttr; if (reader.Prefix == "xmlns" || reader.Prefix == string.Empty && reader.LocalName == "xmlns") { newAttr = new XmlDiffViewAttribute(reader.LocalName, reader.Prefix, reader.NamespaceURI, reader.Value); if (this._bIgnoreNamespaces) { newAttr._op = XmlDiffViewOperation.Ignore; } } else { var str = this._bIgnoreWhitespace ? XmlDiffView.NormalizeText(reader.Value) : reader.Value; newAttr = new XmlDiffViewAttribute(reader.LocalName, reader.Prefix, reader.NamespaceURI, str); } ((XmlDiffViewElement)parent).InsertAttributeAfter(newAttr, this._loadState._curLastAttribute); this._loadState._curLastAttribute = newAttr; } if (!bEmptyElement) { while (reader.Read()) { if (reader.NodeType != XmlNodeType.Whitespace) { XmlDiffViewNode newChild = null; switch (reader.NodeType) { case XmlNodeType.Element: var isEmptyElement = reader.IsEmptyElement; var xmlDiffViewElement = new XmlDiffViewElement(reader.LocalName, reader.Prefix, reader.NamespaceURI, this._bIgnorePrefixes); this.LoadSourceChildNodes(xmlDiffViewElement, reader, isEmptyElement); newChild = xmlDiffViewElement; break; case XmlNodeType.Attribute: Debug.Assert(false, "We should never get to this point, attributes should be read at the beginning of thid method."); break; case XmlNodeType.Text: newChild = new XmlDiffViewCharData(this._bIgnoreWhitespace ? XmlDiffView.NormalizeText(reader.Value) : reader.Value, XmlNodeType.Text); break; case XmlNodeType.CDATA: newChild = new XmlDiffViewCharData(reader.Value, XmlNodeType.CDATA); break; case XmlNodeType.EntityReference: newChild = new XmlDiffViewER(reader.Name); break; case XmlNodeType.ProcessingInstruction: newChild = new XmlDiffViewPI(reader.Name, reader.Value); if (this._bIgnorePI) { newChild._op = XmlDiffViewOperation.Ignore; break; } break; case XmlNodeType.Comment: newChild = new XmlDiffViewCharData(reader.Value, XmlNodeType.Comment); if (this._bIgnoreComments) { newChild._op = XmlDiffViewOperation.Ignore; break; } break; case XmlNodeType.DocumentType: newChild = new XmlDiffViewDocumentType(reader.Name, reader.GetAttribute("PUBLIC"), reader.GetAttribute("SYSTEM"), reader.Value); if (this._bIgnoreDtd) { newChild._op = XmlDiffViewOperation.Ignore; break; } break; case XmlNodeType.SignificantWhitespace: if (reader.XmlSpace == XmlSpace.Preserve) { newChild = new XmlDiffViewCharData(reader.Value, XmlNodeType.SignificantWhitespace); if (this._bIgnoreWhitespace) { newChild._op = XmlDiffViewOperation.Ignore; break; } break; } break; case XmlNodeType.EndElement: goto label_29; case XmlNodeType.XmlDeclaration: newChild = new XmlDiffViewXmlDeclaration(XmlDiffView.NormalizeText(reader.Value)); if (this._bIgnoreXmlDecl) { newChild._op = XmlDiffViewOperation.Ignore; break; } break; default: Debug.Assert(false, "Invalid node type"); break; } parent.InsertChildAfter(newChild, this._loadState._curLastChild, true); this._loadState._curLastChild = newChild; } } } label_29: this._loadState = loadState; }
/// <summary> /// Adds a node object to the collection. /// </summary> /// <param name="node">node object to add</param> public void AddNode(XmlDiffViewNode node) { Debug.Assert(this.count < ChunkSize); this.nodes[this.count++] = node; }