private void WalkTreeOnChangeNode( DiffgramParentOperation diffParent, XmlDiffNode sourceNode, XmlDiffNode targetNode, XmlDiffOperation op ) { Debug.Assert( sourceNode.NodeType != XmlDiffNodeType.Element && targetNode.NodeType != XmlDiffNodeType.Element ); DiffgramChangeNode changeOp = new DiffgramChangeNode( sourceNode, targetNode, op, 0 ); if ( sourceNode.HasChildNodes || targetNode.HasChildNodes ) { WalkTreeGenerateDiffgramMatch( changeOp, (XmlDiffParentNode) sourceNode, (XmlDiffParentNode) targetNode ); } diffParent.InsertAtEnd( changeOp ); }
// produces <change> element in diffgram private void OnChange( DiffgramParentOperation parent ) { EditScriptChange chOp = _editScript as EditScriptChange; Debug.Assert( chOp._targetIndex == _curTargetIndex ); Debug.Assert( chOp._sourceIndex == _curSourceIndex ); XmlDiffNode sourceRoot = _sourceNodes[ chOp._sourceIndex ]; XmlDiffNode targetRoot = _targetNodes[ chOp._targetIndex ]; Debug.Assert( !( sourceRoot is XmlDiffShrankNode) ); Debug.Assert( !( targetRoot is XmlDiffShrankNode) ); // adjust current position _curSourceIndex--; _curTargetIndex--; // move to next edit script operation _editScript = _editScript._nextEditScript; DiffgramOperation diffgramNode = null; if ( _bBuildingAddTree ) { // <add> changed node to the new location if ( targetRoot.NodeType == XmlDiffNodeType.Element ) diffgramNode = new DiffgramAddNode( targetRoot, 0 ); else diffgramNode = new DiffgramAddSubtrees( targetRoot, 0, !_xmlDiff.IgnoreChildOrder ); // <remove> old node from old location -> add to postponed operations bool bSubtree = sourceRoot.NodeType != XmlDiffNodeType.Element; PostponedRemoveNode( sourceRoot, bSubtree, 0, //AddToPosponedOperations( new DiffgramRemoveNode( sourceRoot, bSubtree, 0 ), chOp._sourceIndex, chOp._sourceIndex ); // recursively process children if ( sourceRoot.Left < chOp._sourceIndex || targetRoot.Left < chOp._targetIndex ) { Debug.Assert( targetRoot.NodeType == XmlDiffNodeType.Element ); GenerateDiffgramAdd( (DiffgramParentOperation)diffgramNode, sourceRoot.Left, targetRoot.Left ); } // add attributes, if element if ( targetRoot.NodeType == XmlDiffNodeType.Element ) GenerateAddDiffgramForAttributes( (DiffgramParentOperation)diffgramNode, (XmlDiffElement)targetRoot ); } else { ulong opid = 0; // change of namespace or prefix -> get the appropriate operation id if ( !_xmlDiff.IgnoreNamespaces && sourceRoot.NodeType == XmlDiffNodeType.Element ) { XmlDiffElement sourceEl = (XmlDiffElement)sourceRoot; XmlDiffElement targetEl = (XmlDiffElement)targetRoot; if ( sourceEl.LocalName == targetEl.LocalName ) { opid = GetNamespaceChangeOpid( sourceEl.NamespaceURI, sourceEl.Prefix, targetEl.NamespaceURI, targetEl.Prefix ); } } if ( sourceRoot.NodeType == XmlDiffNodeType.Element ) { if ( XmlDiff.IsChangeOperationOnAttributesOnly( chOp._changeOp ) ) diffgramNode = new DiffgramPosition( sourceRoot ); else { Debug.Assert( (int)chOp._changeOp == (int)XmlDiffOperation.ChangeElementName || ( (int)chOp._changeOp >= (int)XmlDiffOperation.ChangeElementNameAndAttr1 && (int)chOp._changeOp <= (int)XmlDiffOperation.ChangeElementNameAndAttr2 ) ); diffgramNode = new DiffgramChangeNode( sourceRoot, targetRoot, XmlDiffOperation.ChangeElementName, opid ); } // recursively process children if ( sourceRoot.Left < chOp._sourceIndex || targetRoot.Left < chOp._targetIndex ) { GenerateDiffgramMatch( (DiffgramParentOperation) diffgramNode, sourceRoot.Left, targetRoot.Left ); } GenerateChangeDiffgramForAttributes( (DiffgramParentOperation)diffgramNode, (XmlDiffElement)sourceRoot, (XmlDiffElement)targetRoot ); } else { // '<change>' diffgramNode = new DiffgramChangeNode( sourceRoot, targetRoot, chOp._changeOp, opid ); Debug.Assert( !sourceRoot.HasChildNodes ); } } parent.InsertAtBeginning( diffgramNode ); }
private void WalkTreeOnChangeElement( DiffgramParentOperation diffParent, XmlDiffElement sourceElement, XmlDiffElement targetElement, XmlDiffOperation op ) { DiffgramParentOperation diffOp; if ( XmlDiff.IsChangeOperationOnAttributesOnly( op ) ) { diffOp = new DiffgramPosition( sourceElement ); } else { ulong opid = 0; if ( !_xmlDiff.IgnoreNamespaces && sourceElement.LocalName == targetElement.LocalName) { opid = GetNamespaceChangeOpid( sourceElement.NamespaceURI, sourceElement.Prefix, targetElement.NamespaceURI, targetElement.Prefix ); } Debug.Assert( (int)op >= (int)XmlDiffOperation.ChangeElementName && (int)op <= (int)XmlDiffOperation.ChangeElementNameAndAttr3 ); diffOp = new DiffgramChangeNode( sourceElement, targetElement, XmlDiffOperation.ChangeElementName, opid ); } GenerateChangeDiffgramForAttributes( diffOp, sourceElement, targetElement ); if ( sourceElement.HasChildNodes || targetElement.HasChildNodes ) { WalkTreeGenerateDiffgramMatch( diffOp, sourceElement, targetElement ); } diffParent.InsertAtEnd( diffOp ); }