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 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); } } }
static XmlDiffPathNodeList SelectAbsoluteNodes(XmlDiffViewParentNode rootNode, string path) { Debug.Assert(path[0] == '/'); int pos = 1; XmlDiffViewNode node = rootNode; //why??this line screws up ncover: for (;;) while (true) { 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); } } throw new InvalidOperationException(); // This is necessary for NCover. Otherwise NCover screws up the output when instrumenting. }
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); } }
internal static XmlDiffPathNodeList SelectNodes(XmlDiffViewParentNode rootNode, XmlDiffViewParentNode currentParentNode, string xmlDiffPathExpr) { switch (xmlDiffPathExpr[0]) { case '/': return(SelectAbsoluteNodes(rootNode, xmlDiffPathExpr)); case '@': if (xmlDiffPathExpr.Length < 2) { OnInvalidExpression(xmlDiffPathExpr); } if (xmlDiffPathExpr[1] == '*') { return(SelectAllAttributes((XmlDiffViewElement)currentParentNode)); } else { return(SelectAttributes((XmlDiffViewElement)currentParentNode, xmlDiffPathExpr)); } case '*': if (xmlDiffPathExpr.Length == 1) { return(SelectAllChildren(currentParentNode)); } else { OnInvalidExpression(xmlDiffPathExpr); return(null); } default: return(SelectChildNodes(currentParentNode, xmlDiffPathExpr, 0)); } }
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 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 = (opidAttr == string.Empty) ? 0 : int.Parse(opidAttr); if (nodeType == XmlNodeType.Attribute) { Debug.Assert(name != string.Empty); XmlDiffViewAttribute newAttr = new XmlDiffViewAttribute(name, prefix, ns, diffgramElement.InnerText); newAttr._op = XmlDiffViewOperation.Add; newAttr._opid = 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, _bIgnorePrefixes); 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); 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._op = XmlDiffViewOperation.Add; newNode._opid = opid; sourceParent.InsertChildAfter(newNode, currentPosition, false); currentPosition = newNode; } }
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 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; } } }
private void LoadSourceChildNodes(XmlDiffViewParentNode parent, XmlReader reader, bool bEmptyElement) { LoadState savedLoadState = _loadState; _loadState.Reset(); // load attributes while (reader.MoveToNextAttribute()) { XmlDiffViewAttribute attr; if (reader.Prefix == "xmlns" || (reader.Prefix == string.Empty && reader.LocalName == "xmlns")) { attr = new XmlDiffViewAttribute(reader.LocalName, reader.Prefix, reader.NamespaceURI, reader.Value); if (_bIgnoreNamespaces) { attr._op = XmlDiffViewOperation.Ignore; } } else { string attrValue = _bIgnoreWhitespace ? NormalizeText(reader.Value) : reader.Value; attr = new XmlDiffViewAttribute(reader.LocalName, reader.Prefix, reader.NamespaceURI, attrValue); } ((XmlDiffViewElement)parent).InsertAttributeAfter(attr, _loadState._curLastAttribute); _loadState._curLastAttribute = attr; } // empty element -> return, do not load chilren if (bEmptyElement) { goto End; } // load children while (reader.Read()) { // ignore whitespaces between nodes if (reader.NodeType == XmlNodeType.Whitespace) { continue; } XmlDiffViewNode child = null; switch (reader.NodeType) { case XmlNodeType.Element: bool bEmptyEl = reader.IsEmptyElement; XmlDiffViewElement elem = new XmlDiffViewElement(reader.LocalName, reader.Prefix, reader.NamespaceURI, _bIgnorePrefixes); LoadSourceChildNodes(elem, reader, bEmptyEl); child = elem; 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: child = new XmlDiffViewCharData((_bIgnoreWhitespace) ? NormalizeText(reader.Value) : reader.Value, XmlNodeType.Text); break; case XmlNodeType.CDATA: child = new XmlDiffViewCharData(reader.Value, XmlNodeType.CDATA); break; case XmlNodeType.EntityReference: child = new XmlDiffViewER(reader.Name); break; case XmlNodeType.Comment: child = new XmlDiffViewCharData(reader.Value, XmlNodeType.Comment); if (_bIgnoreComments) { child._op = XmlDiffViewOperation.Ignore; } break; case XmlNodeType.ProcessingInstruction: child = new XmlDiffViewPI(reader.Name, reader.Value); if (_bIgnorePI) { child._op = XmlDiffViewOperation.Ignore; } break; case XmlNodeType.SignificantWhitespace: if (reader.XmlSpace == XmlSpace.Preserve) { child = new XmlDiffViewCharData(reader.Value, XmlNodeType.SignificantWhitespace); if (_bIgnoreWhitespace) { child._op = XmlDiffViewOperation.Ignore; } } break; case XmlNodeType.XmlDeclaration: child = new XmlDiffViewXmlDeclaration(NormalizeText(reader.Value)); if (_bIgnoreXmlDecl) { child._op = XmlDiffViewOperation.Ignore; } break; case XmlNodeType.EndElement: goto End; case XmlNodeType.DocumentType: child = new XmlDiffViewDocumentType(reader.Name, reader.GetAttribute("PUBLIC"), reader.GetAttribute("SYSTEM"), reader.Value); if (_bIgnoreDtd) { child._op = XmlDiffViewOperation.Ignore; } break; default: Debug.Assert(false, "Invalid node type"); break; } parent.InsertChildAfter(child, _loadState._curLastChild, true); _loadState._curLastChild = child; } End: _loadState = savedLoadState; }
static XmlDiffPathNodeList SelectChildNodes(XmlDiffViewParentNode parentNode, string path, int startPos) { int pos = startPos; XmlDiffPathNodeList nodeList = null; //NCOVER DOESN'T LIKE: for (;;) while (true) { 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); }