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); } } }
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; } } }
static XmlDiffPathNodeList SelectAttributes(XmlDiffViewElement parentElement, string path) { Debug.Assert(path[0] == '@'); int pos = 1; XmlDiffPathNodeList nodeList = null; for (;;) { string name = ReadAttrName(path, ref pos); if (nodeList == null) { if (pos == path.Length) { nodeList = new XmlDiffPathSingleNodeList(); } else { nodeList = new XmlDiffPathMultiNodeList(); } } XmlDiffViewAttribute attr = parentElement.GetAttribute(name); if (attr == null) { OnNoMatchingNode(path); } nodeList.AddNode(attr); if (pos == path.Length) { break; } else if (path[pos] == '|') { pos++; if (path[pos] != '@') { OnInvalidExpression(path); } pos++; } else { OnInvalidExpression(path); } } return(nodeList); }
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); } } }
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; } } }
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); }
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(); 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._ns = (ns == null) ? ((XmlDiffViewElement)node)._ns : 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._ns = (ns == null) ? ((XmlDiffViewAttribute)node)._ns : ns; changeInfo._value = diffgramElement.InnerText; break; case XmlNodeType.Text: case XmlNodeType.CDATA: Debug.Assert(diffgramElement.FirstChild != null); changeInfo._value = diffgramElement.InnerText; break; case XmlNodeType.Comment: Debug.Assert(diffgramElement.FirstChild != null); Debug.Assert(diffgramElement.FirstChild.NodeType == XmlNodeType.Comment); changeInfo._value = 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._value = diffgramElement.FirstChild.Value; } else { changeInfo._localName = name; changeInfo._value = ((XmlDiffViewPI)node)._value; } break; case XmlNodeType.EntityReference: Debug.Assert(name != null); changeInfo._localName = name; break; case XmlNodeType.XmlDeclaration: Debug.Assert(diffgramElement.FirstChild != null); changeInfo._value = 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._ns = diffgramElement.GetAttribute("systemId"); } else { changeInfo._ns = ((XmlDiffViewDocumentType)node)._systemId; } if (diffgramElement.FirstChild != null) { changeInfo._value = diffgramElement.InnerText; } else { changeInfo._value = ((XmlDiffViewDocumentType)node)._subset; } break; default: Debug.Assert(false, "Invalid node type."); break; } node._changeInfo = changeInfo; node._op = XmlDiffViewOperation.Change; string opidAttr = diffgramElement.GetAttribute("opid"); if (opidAttr != string.Empty) { node._opid = int.Parse(opidAttr); } if (node._nodeType == XmlNodeType.Element && diffgramElement.FirstChild != null) { ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)node); } }
private void ApplyDiffgram(XmlNode diffgramParent, XmlDiffViewParentNode sourceParent) { sourceParent.CreateSourceNodesIndex(); XmlDiffViewNode currentPosition = null; IEnumerator diffgramChildren = diffgramParent.ChildNodes.GetEnumerator(); while (diffgramChildren.MoveNext()) { XmlNode diffgramNode = (XmlNode)diffgramChildren.Current; if (diffgramNode.NodeType == XmlNodeType.Comment) { continue; } XmlElement diffgramElement = diffgramChildren.Current as XmlElement; if (diffgramElement == null) { throw new Exception("Invalid node in diffgram."); } if (diffgramElement.NamespaceURI != XmlDiff.NamespaceUri) { throw new Exception("Invalid element in diffgram."); } string matchAttr = diffgramElement.GetAttribute("match"); XmlDiffPathNodeList matchNodes = null; if (matchAttr != string.Empty) { matchNodes = XmlDiffPath.SelectNodes(_doc, sourceParent, matchAttr); } switch (diffgramElement.LocalName) { case "node": if (matchNodes.Count != 1) { throw new Exception("The 'match' attribute of 'node' element must select a single node."); } matchNodes.MoveNext(); if (diffgramElement.ChildNodes.Count > 0) { ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)matchNodes.Current); } currentPosition = matchNodes.Current; break; case "add": if (matchAttr != string.Empty) { OnAddMatch(diffgramElement, matchNodes, sourceParent, ref currentPosition); } else { string typeAttr = diffgramElement.GetAttribute("type"); if (typeAttr != string.Empty) { OnAddNode(diffgramElement, typeAttr, sourceParent, ref currentPosition); } else { OnAddFragment(diffgramElement, sourceParent, ref currentPosition); } } break; case "remove": OnRemove(diffgramElement, matchNodes, sourceParent, ref currentPosition); break; case "change": OnChange(diffgramElement, matchNodes, sourceParent, ref currentPosition); break; } } }
/// <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> /// 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> /// 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; } } }
static XmlDiffPathNodeList SelectChildNodes(XmlDiffViewParentNode parentNode, string path, int startPos) { int pos = startPos; XmlDiffPathNodeList nodeList = null; for (;;) { int nodePos = ReadPosition(path, ref pos); if (pos == path.Length) { nodeList = new XmlDiffPathSingleNodeList(); } else { nodeList = new XmlDiffPathMultiNodeList(); } if (nodePos <= 0 || nodePos > parentNode._sourceChildNodesCount) { OnNoMatchingNode(path); } nodeList.AddNode(parentNode.GetSourceChildNode(nodePos - 1)); if (pos == path.Length) { break; } else if (path[pos] == '|') { pos++; } else if (path[pos] == '-') { pos++; int endNodePos = ReadPosition(path, ref pos); if (endNodePos <= 0 || endNodePos > parentNode._sourceChildNodesCount) { OnNoMatchingNode(path); } while (nodePos < endNodePos) { nodePos++; nodeList.AddNode(parentNode.GetSourceChildNode(nodePos - 1)); } if (pos == path.Length) { break; } else if (path[pos] == '|') { pos++; } else { OnInvalidExpression(path); } } } return(nodeList); }