예제 #1
0
        private void ComputeHashXmlDiffChildren(HashAlgorithm ha, XmlDiffParentNode parent)
        {
            var i = 0;

            if (this._bIgnoreChildOrder)
            {
                ulong u = 0;
                for (var xmlDiffNode = parent.FirstChildNode; xmlDiffNode != null; xmlDiffNode = xmlDiffNode._nextSibling)
                {
                    u += xmlDiffNode.HashValue;
                    ++i;
                }
                ha.AddULong(u);
            }
            else
            {
                for (var xmlDiffNode = parent.FirstChildNode; xmlDiffNode != null; xmlDiffNode = xmlDiffNode._nextSibling)
                {
                    ha.AddULong(xmlDiffNode.HashValue);
                    ++i;
                }
            }
            if (i == 0)
            {
                return;
            }
            ha.AddInt(i);
        }
//    internal bool _nodeOrDescendantMatches = false;

// Constructors
    internal XmlDiffNode( int position ) 
	{
        _parent = null;
        _nextSibling = null;
        _position = position;
        _bExpanded = false;
    }
예제 #3
0
//    internal bool _nodeOrDescendantMatches = false;

// Constructors
        internal XmlDiffNode(int position)
        {
            _parent      = null;
            _nextSibling = null;
            _position    = position;
            _bExpanded   = false;
        }
예제 #4
0
 internal XmlDiffNode(int position)
 {
     this._parent      = (XmlDiffParentNode)null;
     this._nextSibling = (XmlDiffNode)null;
     this._position    = position;
     this._bExpanded   = false;
 }
예제 #5
0
// Methods
        internal override void WriteTo(XmlWriter xmlWriter, XmlDiff xmlDiff)
        {
            if (!_bSorted)
            {
                Sort();
            }

            xmlWriter.WriteStartElement(XmlDiff.Prefix, "add", XmlDiff.NamespaceUri);
            if (_operationID != 0)
            {
                xmlWriter.WriteAttributeString("opid", _operationID.ToString());
            }

            // namespaces
            if (_bNeedNamespaces)
            {
                Hashtable         definedPrefixes = new Hashtable();
                XmlDiffParentNode parent          = _firstTargetNode._parent;
                while (parent != null)
                {
                    if (parent._bDefinesNamespaces)
                    {
                        XmlDiffElement el = (XmlDiffElement)parent;
                        XmlDiffAttributeOrNamespace curNs = el._attributes;
                        while (curNs != null && curNs.NodeType == XmlDiffNodeType.Namespace)
                        {
                            if (definedPrefixes[curNs.Prefix] == null)
                            {
                                if (curNs.Prefix == string.Empty)
                                {
                                    xmlWriter.WriteAttributeString("xmlns", XmlDiff.XmlnsNamespaceUri, curNs.NamespaceURI);
                                }
                                else
                                {
                                    xmlWriter.WriteAttributeString("xmlns", curNs.Prefix, XmlDiff.XmlnsNamespaceUri, curNs.NamespaceURI);
                                }
                                definedPrefixes[curNs.Prefix] = curNs.Prefix;
                            }
                            curNs = (XmlDiffAttributeOrNamespace)curNs._nextSibling;
                        }
                    }
                    parent = parent._parent;
                }
            }

            // output nodes
            XmlDiffNode node = _firstTargetNode;

            for (;;)
            {
                node.WriteTo(xmlWriter);
                if (node == _lastTargetNode)
                {
                    break;
                }
                node = node._nextSibling;
            }
            xmlWriter.WriteEndElement();
        }
예제 #6
0
 internal void LoadChildNodes(XmlDiffParentNode parent, XmlNode parentDomNode)
 {
         var curLastChild = this._curLastChild;
   this._curLastChild = (XmlDiffNode) null;
         var attributes = (XmlNamedNodeMap) parentDomNode.Attributes;
   if (attributes != null && attributes.Count > 0)
   {
     foreach (XmlAttribute xmlAttribute in attributes)
     {
       if (xmlAttribute.Prefix == "xmlns")
       {
         if (!this._XmlDiff.IgnoreNamespaces)
         {
                         var xmlDiffNamespace = new XmlDiffNamespace(xmlAttribute.LocalName, xmlAttribute.Value);
           xmlDiffNamespace.ComputeHashValue(this._xmlHash);
           this.InsertAttributeOrNamespace((XmlDiffElement) parent, (XmlDiffAttributeOrNamespace) xmlDiffNamespace);
         }
       }
       else if (xmlAttribute.Prefix == string.Empty && xmlAttribute.LocalName == "xmlns")
       {
         if (!this._XmlDiff.IgnoreNamespaces)
         {
                         var xmlDiffNamespace = new XmlDiffNamespace(string.Empty, xmlAttribute.Value);
           xmlDiffNamespace.ComputeHashValue(this._xmlHash);
           this.InsertAttributeOrNamespace((XmlDiffElement) parent, (XmlDiffAttributeOrNamespace) xmlDiffNamespace);
         }
       }
       else
       {
         var str = this._XmlDiff.IgnoreWhitespace ? XmlDiff.NormalizeText(xmlAttribute.Value) : xmlAttribute.Value;
                     var xmlDiffAttribute = new XmlDiffAttribute(xmlAttribute.LocalName, xmlAttribute.Prefix, xmlAttribute.NamespaceURI, str);
         xmlDiffAttribute.ComputeHashValue(this._xmlHash);
         this.InsertAttributeOrNamespace((XmlDiffElement) parent, (XmlDiffAttributeOrNamespace) xmlDiffAttribute);
       }
     }
   }
         var childNodes = parentDomNode.ChildNodes;
   if (childNodes.Count != 0)
   {
     var childPosition = 0;
             var enumerator = childNodes.GetEnumerator();
     while (enumerator.MoveNext())
     {
       if (((XmlNode) enumerator.Current).NodeType != XmlNodeType.Whitespace)
       {
                     var newChild = this.LoadNode((XmlNode) enumerator.Current, ref childPosition);
         if (newChild != null)
           this.InsertChild(parent, newChild);
       }
     }
   }
   this._curLastChild = curLastChild;
 }
예제 #7
0
 private void InsertChild(XmlDiffParentNode parent, XmlDiffNode newChild)
 {
   if (this._XmlDiff.IgnoreChildOrder)
   {
             var node1 = parent.FirstChildNode;
             var childNode = (XmlDiffNode) null;
     for (; node1 != null && XmlDiffDocument.OrderChildren(node1, newChild) <= 0; node1 = node1._nextSibling)
       childNode = node1;
     parent.InsertChildNodeAfter(childNode, newChild);
   }
   else
   {
     parent.InsertChildNodeAfter(this._curLastChild, newChild);
     this._curLastChild = newChild;
   }
 }
예제 #8
0
        // Inserts the 'newChild' node. If child order is significant, the new child is
        // inserted at the end of all child nodes. If the child order is not signoficant,
        // the new node is sorted into the other child nodes.
        private void InsertChild(XmlDiffParentNode parent, XmlDiffNode newChild)
        {
            if (_XmlDiff.IgnoreChildOrder)
            {
                XmlDiffNode curChild  = parent.FirstChildNode;
                XmlDiffNode prevChild = null;

                while (curChild != null && (OrderChildren(curChild, newChild) <= 0))
                {
                    prevChild = curChild;
                    curChild  = curChild._nextSibling;
                }
                parent.InsertChildNodeAfter(prevChild, newChild);
            }
            else
            {
                parent.InsertChildNodeAfter(_curLastChild, newChild);
                _curLastChild = newChild;
            }
        }
예제 #9
0
        private void ComputeHashXmlDiffChildren(HashAlgorithm ha, XmlDiffParentNode parent)
        {
            int childrenCount = 0;

            if (_bIgnoreChildOrder)
            {
                ulong       totalHash = 0;
                XmlDiffNode curChild  = parent.FirstChildNode;
                while (curChild != null)
                {
                    Debug.Assert(!(curChild is XmlDiffAttributeOrNamespace));
                    Debug.Assert(curChild.HashValue != 0);

                    totalHash += curChild.HashValue;
                    childrenCount++;
                    curChild = curChild._nextSibling;
                }
                ha.AddULong(totalHash);
            }
            else
            {
                XmlDiffNode curChild = parent.FirstChildNode;
                while (curChild != null)
                {
                    Debug.Assert(!(curChild is XmlDiffAttributeOrNamespace));
                    Debug.Assert(curChild.HashValue != 0);

                    ha.AddULong(curChild.HashValue);
                    childrenCount++;
                    curChild = curChild._nextSibling;
                }
            }

            if (childrenCount != 0)
            {
                ha.AddInt(childrenCount);
            }
        }
예제 #10
0
    internal void LoadChildNodes(XmlDiffParentNode parent, XmlReader reader, bool bEmptyElement)
    {
            var curLastChild = this._curLastChild;
      this._curLastChild = (XmlDiffNode) null;
      while (reader.MoveToNextAttribute())
      {
        if (reader.Prefix == "xmlns")
        {
          if (!this._XmlDiff.IgnoreNamespaces)
          {
                        var xmlDiffNamespace = new XmlDiffNamespace(reader.LocalName, reader.Value);
            xmlDiffNamespace.ComputeHashValue(this._xmlHash);
            this.InsertAttributeOrNamespace((XmlDiffElement) parent, (XmlDiffAttributeOrNamespace) xmlDiffNamespace);
          }
        }
        else if (reader.Prefix == string.Empty && reader.LocalName == "xmlns")
        {
          if (!this._XmlDiff.IgnoreNamespaces)
          {
                        var xmlDiffNamespace = new XmlDiffNamespace(string.Empty, reader.Value);
            xmlDiffNamespace.ComputeHashValue(this._xmlHash);
            this.InsertAttributeOrNamespace((XmlDiffElement) parent, (XmlDiffAttributeOrNamespace) xmlDiffNamespace);
          }
        }
        else
        {
          var str = this._XmlDiff.IgnoreWhitespace ? XmlDiff.NormalizeText(reader.Value) : reader.Value;
                    var xmlDiffAttribute = new XmlDiffAttribute(reader.LocalName, reader.Prefix, reader.NamespaceURI, str);
          xmlDiffAttribute.ComputeHashValue(this._xmlHash);
          this.InsertAttributeOrNamespace((XmlDiffElement) parent, (XmlDiffAttributeOrNamespace) xmlDiffAttribute);
        }
      }
      if (!bEmptyElement)
      {
        var position = 0;
        if (reader.Read())
        {
          do
          {
            if (reader.NodeType != XmlNodeType.Whitespace)
            {
              switch (reader.NodeType)
              {
                case XmlNodeType.Element:
                  var isEmptyElement = reader.IsEmptyElement;
                                    var xmlDiffElement = new XmlDiffElement(++position, reader.LocalName, reader.Prefix, reader.NamespaceURI);
                  this.LoadChildNodes((XmlDiffParentNode) xmlDiffElement, reader, isEmptyElement);
                  xmlDiffElement.ComputeHashValue(this._xmlHash);
                  this.InsertChild(parent, (XmlDiffNode) xmlDiffElement);
                  break;
                case XmlNodeType.Text:
                  var str = this._XmlDiff.IgnoreWhitespace ? XmlDiff.NormalizeText(reader.Value) : reader.Value;
                                    var xmlDiffCharData1 = new XmlDiffCharData(++position, str, XmlDiffNodeType.Text);
                  xmlDiffCharData1.ComputeHashValue(this._xmlHash);
                  this.InsertChild(parent, (XmlDiffNode) xmlDiffCharData1);
                  break;
                case XmlNodeType.CDATA:
                                    var xmlDiffCharData2 = new XmlDiffCharData(++position, reader.Value, XmlDiffNodeType.CDATA);
                  xmlDiffCharData2.ComputeHashValue(this._xmlHash);
                  this.InsertChild(parent, (XmlDiffNode) xmlDiffCharData2);
                  break;
                case XmlNodeType.EntityReference:
                                    var xmlDiffEr = new XmlDiffER(++position, reader.Name);
                  xmlDiffEr.ComputeHashValue(this._xmlHash);
                  this.InsertChild(parent, (XmlDiffNode) xmlDiffEr);
                  break;
                case XmlNodeType.ProcessingInstruction:
                  ++position;
                  if (!this._XmlDiff.IgnorePI)
                  {
                                        var xmlDiffPi = new XmlDiffPI(position, reader.Name, reader.Value);
                    xmlDiffPi.ComputeHashValue(this._xmlHash);
                    this.InsertChild(parent, (XmlDiffNode) xmlDiffPi);
                    break;
                  }
                  break;
                case XmlNodeType.Comment:
                  ++position;
                  if (!this._XmlDiff.IgnoreComments)
                  {
                                        var xmlDiffCharData3 = new XmlDiffCharData(position, reader.Value, XmlDiffNodeType.Comment);
                    xmlDiffCharData3.ComputeHashValue(this._xmlHash);
                    this.InsertChild(parent, (XmlDiffNode) xmlDiffCharData3);
                    break;
                  }
                  break;
                case XmlNodeType.DocumentType:
                  ++position;
                  if (!this._XmlDiff.IgnoreDtd)
                  {
                                        var diffDocumentType = new XmlDiffDocumentType(position, reader.Name, reader.GetAttribute("PUBLIC"), reader.GetAttribute("SYSTEM"), reader.Value);
                    diffDocumentType.ComputeHashValue(this._xmlHash);
                    this.InsertChild(parent, (XmlDiffNode) diffDocumentType);
                    break;
                  }
                  break;
                case XmlNodeType.SignificantWhitespace:
                  if (reader.XmlSpace == XmlSpace.Preserve)
                  {
                    ++position;
                    if (!this._XmlDiff.IgnoreWhitespace)
                    {
                                            var xmlDiffCharData3 = new XmlDiffCharData(position, reader.Value, XmlDiffNodeType.SignificantWhitespace);
                      xmlDiffCharData3.ComputeHashValue(this._xmlHash);
                      this.InsertChild(parent, (XmlDiffNode) xmlDiffCharData3);
                      break;
                    }
                    break;
                  }
                  break;
                case XmlNodeType.EndElement:
                  goto label_29;
                case XmlNodeType.XmlDeclaration:
                  ++position;
                  if (!this._XmlDiff.IgnoreXmlDecl)
                  {
                                        var diffXmlDeclaration = new XmlDiffXmlDeclaration(position, XmlDiff.NormalizeXmlDeclaration(reader.Value));
                    diffXmlDeclaration.ComputeHashValue(this._xmlHash);
                    this.InsertChild(parent, (XmlDiffNode) diffXmlDeclaration);
                    break;
                  }
                  break;
              }
            }
          }
          while (reader.Read());
        }
      }
label_29:
      this._curLastChild = curLastChild;
    }
    // Loads child nodes of the 'parent' node
    internal void LoadChildNodes( XmlDiffParentNode parent, XmlNode parentDomNode ) 
    {
        XmlDiffNode savedLastChild = _curLastChild;
        _curLastChild = null;

        // load attributes & namespace nodes
        XmlNamedNodeMap attribs = parentDomNode.Attributes;
        if ( attribs != null && attribs.Count > 0 ) 
        {
            IEnumerator attrEnum = attribs.GetEnumerator();
            while ( attrEnum.MoveNext() ) 
            {
                XmlAttribute attr = (XmlAttribute)attrEnum.Current;
                if ( attr.Prefix == "xmlns" )
                {
                    if ( !_XmlDiff.IgnoreNamespaces ) 
                    {
                        XmlDiffNamespace nsNode = new XmlDiffNamespace( attr.LocalName, attr.Value );
                        nsNode.ComputeHashValue( _xmlHash );
                        InsertAttributeOrNamespace( (XmlDiffElement)parent, nsNode );
                    }
                }
                else if ( attr.Prefix == string.Empty && attr.LocalName == "xmlns" )
                {
                    if ( !_XmlDiff.IgnoreNamespaces ) 
                    {
                        XmlDiffNamespace nsNode = new XmlDiffNamespace( string.Empty, attr.Value );
                        nsNode.ComputeHashValue( _xmlHash );
                        InsertAttributeOrNamespace( (XmlDiffElement)parent, nsNode );
                    }
                }
                else
                {
                    string attrValue = _XmlDiff.IgnoreWhitespace ? XmlDiff.NormalizeText( attr.Value ) : attr.Value;
                    XmlDiffAttribute newAttr = new XmlDiffAttribute( attr.LocalName, attr.Prefix, attr.NamespaceURI, attrValue );
                    newAttr.ComputeHashValue( _xmlHash );
                    InsertAttributeOrNamespace( (XmlDiffElement)parent, newAttr );
                }
            }
        }

        // load children
        XmlNodeList children = parentDomNode.ChildNodes;
        if ( children.Count == 0 )
            goto End;

        int childPosition = 0;
        IEnumerator childEnum = children.GetEnumerator();
        while ( childEnum.MoveNext() )
        {
            XmlNode node = (XmlNode)childEnum.Current;

            // ignore whitespaces between nodes
            if ( node.NodeType == XmlNodeType.Whitespace )
                continue;

            XmlDiffNode newDiffNode = LoadNode( (XmlNode)childEnum.Current, ref childPosition );
            if ( newDiffNode != null )
                InsertChild( parent, newDiffNode );
        }

        End:
        _curLastChild = savedLastChild;
    }
예제 #12
0
        // Loads child nodes of the 'parent' node
        internal void LoadChildNodes(XmlDiffParentNode parent, XmlNode parentDomNode)
        {
            XmlDiffNode savedLastChild = _curLastChild;

            _curLastChild = null;

            // load attributes & namespace nodes
            XmlNamedNodeMap attribs = parentDomNode.Attributes;

            if (attribs != null && attribs.Count > 0)
            {
                IEnumerator attrEnum = attribs.GetEnumerator();
                while (attrEnum.MoveNext())
                {
                    XmlAttribute attr = (XmlAttribute)attrEnum.Current;
                    if (attr.Prefix == "xmlns")
                    {
                        if (!_XmlDiff.IgnoreNamespaces)
                        {
                            XmlDiffNamespace nsNode = new XmlDiffNamespace(attr.LocalName, attr.Value);
                            nsNode.ComputeHashValue(_xmlHash);
                            InsertAttributeOrNamespace((XmlDiffElement)parent, nsNode);
                        }
                    }
                    else if (attr.Prefix == string.Empty && attr.LocalName == "xmlns")
                    {
                        if (!_XmlDiff.IgnoreNamespaces)
                        {
                            XmlDiffNamespace nsNode = new XmlDiffNamespace(string.Empty, attr.Value);
                            nsNode.ComputeHashValue(_xmlHash);
                            InsertAttributeOrNamespace((XmlDiffElement)parent, nsNode);
                        }
                    }
                    else
                    {
                        string           attrValue = _XmlDiff.IgnoreWhitespace ? XmlDiff.NormalizeText(attr.Value) : attr.Value;
                        XmlDiffAttribute newAttr   = new XmlDiffAttribute(attr.LocalName, attr.Prefix, attr.NamespaceURI, attrValue);
                        newAttr.ComputeHashValue(_xmlHash);
                        InsertAttributeOrNamespace((XmlDiffElement)parent, newAttr);
                    }
                }
            }

            // load children
            XmlNodeList children = parentDomNode.ChildNodes;

            if (children.Count == 0)
            {
                goto End;
            }

            int         childPosition = 0;
            IEnumerator childEnum     = children.GetEnumerator();

            while (childEnum.MoveNext())
            {
                XmlNode node = (XmlNode)childEnum.Current;

                // ignore whitespaces between nodes
                if (node.NodeType == XmlNodeType.Whitespace)
                {
                    continue;
                }

                XmlDiffNode newDiffNode = LoadNode((XmlNode)childEnum.Current, ref childPosition);
                if (newDiffNode != null)
                {
                    InsertChild(parent, newDiffNode);
                }
            }

End:
            _curLastChild = savedLastChild;
        }
예제 #13
0
        // Loads child nodes of the 'parent' node
        internal void LoadChildNodes(XmlDiffParentNode parent, XmlReader reader, bool bEmptyElement)
        {
            XmlDiffNode savedLastChild = _curLastChild;

            _curLastChild = null;

            // load attributes & namespace nodes
            while (reader.MoveToNextAttribute())
            {
                if (reader.Prefix == "xmlns")
                {
                    if (!_XmlDiff.IgnoreNamespaces)
                    {
                        XmlDiffNamespace nsNode = new XmlDiffNamespace(reader.LocalName, reader.Value);
                        nsNode.ComputeHashValue(_xmlHash);
                        InsertAttributeOrNamespace((XmlDiffElement)parent, nsNode);
                    }
                }
                else if (reader.Prefix == string.Empty && reader.LocalName == "xmlns")
                {
                    if (!_XmlDiff.IgnoreNamespaces)
                    {
                        XmlDiffNamespace nsNode = new XmlDiffNamespace(string.Empty, reader.Value);
                        nsNode.ComputeHashValue(_xmlHash);
                        InsertAttributeOrNamespace((XmlDiffElement)parent, nsNode);
                    }
                }
                else
                {
                    string           attrValue = _XmlDiff.IgnoreWhitespace ? XmlDiff.NormalizeText(reader.Value) : reader.Value;
                    XmlDiffAttribute attr      = new XmlDiffAttribute(reader.LocalName, reader.Prefix, reader.NamespaceURI, attrValue);
                    attr.ComputeHashValue(_xmlHash);
                    InsertAttributeOrNamespace((XmlDiffElement)parent, attr);
                }
            }

            // empty element -> return, do not load chilren
            if (bEmptyElement)
            {
                goto End;
            }

            int childPosition = 0;

            // load children
            if (!reader.Read())
            {
                goto End;
            }

            do
            {
                // ignore whitespaces between nodes
                if (reader.NodeType == XmlNodeType.Whitespace)
                {
                    continue;
                }

                switch (reader.NodeType)
                {
                case XmlNodeType.Element:
                {
                    bool           bEmptyEl = reader.IsEmptyElement;
                    XmlDiffElement elem     = new XmlDiffElement(++childPosition, reader.LocalName, reader.Prefix, reader.NamespaceURI);

                    LoadChildNodes(elem, reader, bEmptyEl);

                    elem.ComputeHashValue(_xmlHash);
                    InsertChild(parent, 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:
                {
                    string          textValue    = (_XmlDiff.IgnoreWhitespace) ? XmlDiff.NormalizeText(reader.Value) : reader.Value;
                    XmlDiffCharData charDataNode = new XmlDiffCharData(++childPosition, textValue, XmlDiffNodeType.Text);
                    charDataNode.ComputeHashValue(_xmlHash);
                    InsertChild(parent, charDataNode);
                    break;
                }

                case XmlNodeType.CDATA:
                {
                    XmlDiffCharData charDataNode = new XmlDiffCharData(++childPosition, reader.Value, XmlDiffNodeType.CDATA);
                    charDataNode.ComputeHashValue(_xmlHash);
                    InsertChild(parent, charDataNode);
                    break;
                }

                case XmlNodeType.EntityReference:
                {
                    XmlDiffER er = new XmlDiffER(++childPosition, reader.Name);
                    er.ComputeHashValue(_xmlHash);
                    InsertChild(parent, er);
                    break;
                }

                case XmlNodeType.Comment:
                {
                    ++childPosition;
                    if (!_XmlDiff.IgnoreComments)
                    {
                        XmlDiffCharData charDataNode = new XmlDiffCharData(childPosition, reader.Value, XmlDiffNodeType.Comment);
                        charDataNode.ComputeHashValue(_xmlHash);
                        InsertChild(parent, charDataNode);
                    }
                    break;
                }

                case XmlNodeType.ProcessingInstruction:
                {
                    ++childPosition;
                    if (!_XmlDiff.IgnorePI)
                    {
                        XmlDiffPI pi = new XmlDiffPI(childPosition, reader.Name, reader.Value);
                        pi.ComputeHashValue(_xmlHash);
                        InsertChild(parent, pi);
                    }
                    break;
                }

                case XmlNodeType.SignificantWhitespace:
                {
                    if (reader.XmlSpace == XmlSpace.Preserve)
                    {
                        ++childPosition;
                        if (!_XmlDiff.IgnoreWhitespace)
                        {
                            XmlDiffCharData charDataNode = new XmlDiffCharData(childPosition, reader.Value, XmlDiffNodeType.SignificantWhitespace);
                            charDataNode.ComputeHashValue(_xmlHash);
                            InsertChild(parent, charDataNode);
                        }
                    }
                    break;
                }

                case XmlNodeType.XmlDeclaration:
                {
                    ++childPosition;
                    if (!_XmlDiff.IgnoreXmlDecl)
                    {
                        XmlDiffXmlDeclaration xmlDecl = new XmlDiffXmlDeclaration(childPosition, XmlDiff.NormalizeXmlDeclaration(reader.Value));
                        xmlDecl.ComputeHashValue(_xmlHash);
                        InsertChild(parent, xmlDecl);
                    }
                    break;
                }

                case XmlNodeType.EndElement:
                    goto End;

                case XmlNodeType.DocumentType:
                    childPosition++;
                    if (!_XmlDiff.IgnoreDtd)
                    {
                        XmlDiffDocumentType docType = new XmlDiffDocumentType(childPosition,
                                                                              reader.Name,
                                                                              reader.GetAttribute("PUBLIC"),
                                                                              reader.GetAttribute("SYSTEM"),
                                                                              reader.Value);
                        docType.ComputeHashValue(_xmlHash);
                        InsertChild(parent, docType);
                    }
                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
            } while (reader.Read());

End:
            _curLastChild = savedLastChild;
        }
예제 #14
0
        private void WalkTreeGenerateDiffgramMatch( DiffgramParentOperation diffParent, XmlDiffParentNode sourceParent, XmlDiffParentNode targetParent )
        {
            XmlDiffNode sourceNode = sourceParent.FirstChildNode;
            XmlDiffNode targetNode = targetParent.FirstChildNode;
            XmlDiffNode needPositionSourceNode = null;

            while ( sourceNode != null || targetNode != null ) {
            if ( sourceNode != null ) {
                if ( targetNode != null ) {
                    XmlDiffOperation op = sourceNode.GetDiffOperation( targetNode, _xmlDiff );
                    // match
                    if ( op == XmlDiffOperation.Match ) {
                        WalkTreeOnMatchNode( diffParent, sourceNode, targetNode, ref needPositionSourceNode );
                    }
                    // no match
                    else {
                        int walkNodesCount = ( sourceNode._parent.ChildNodesCount + targetNode._parent.ChildNodesCount ) / 2;
                        walkNodesCount = (int)( LogMultiplier * Math.Log( (double)walkNodesCount ) + 1 );

                        XmlDiffNode sourceClosestMatchNode = targetNode;
                        XmlDiffNode targetClosestMatchNode = sourceNode;
                        XmlDiffOperation sourceOp = op;
                        XmlDiffOperation targetOp = op;
                        int sourceNodesToAddCount = targetNode.NodesCount;
                        int targetNodesToRemoveCount = sourceNode.NodesCount;

                        XmlDiffNode nextSourceNode = sourceNode._nextSibling;
                        XmlDiffNode nextTargetNode = targetNode._nextSibling;

                        // walk limited number of siblings to find the closest matching node
                        for ( int i = 0; i < walkNodesCount && ( nextTargetNode != null || nextSourceNode != null ); i++ ) {
                            if ( nextTargetNode != null && sourceOp != XmlDiffOperation.Match ) {
                                XmlDiffOperation o = sourceNode.GetDiffOperation( nextTargetNode, _xmlDiff );
                                if ( MinimalTreeDistanceAlgo.OperationCost[(int)o] < MinimalTreeDistanceAlgo.OperationCost[(int)sourceOp] ) {
                                    sourceOp = o;
                                    sourceClosestMatchNode = nextTargetNode;
                                }
                                else {
                                    sourceNodesToAddCount += nextTargetNode.NodesCount;
                                    nextTargetNode = nextTargetNode._nextSibling;
                                }
                            }

                            if ( nextSourceNode != null && targetOp != XmlDiffOperation.Match ) {
                                XmlDiffOperation o = targetNode.GetDiffOperation( nextSourceNode, _xmlDiff );
                                if ( MinimalTreeDistanceAlgo.OperationCost[(int)o] < MinimalTreeDistanceAlgo.OperationCost[(int)targetOp] ) {
                                    targetOp = o;
                                    targetClosestMatchNode = nextSourceNode;
                                }
                                else {
                                    targetNodesToRemoveCount += nextSourceNode.NodesCount;
                                    nextSourceNode = nextSourceNode._nextSibling;
                                }
                            }

                            if ( sourceOp == XmlDiffOperation.Match || targetOp == XmlDiffOperation.Match ) {
                                break;
                            }

                            if ( _xmlDiff.IgnoreChildOrder ) {
                                if ( nextTargetNode != null ) {
                                    if ( XmlDiffDocument.OrderChildren( sourceNode, nextTargetNode ) < 0 ) {
                                        nextTargetNode = null;
                                    }
                                }
                                if ( nextSourceNode != null ) {
                                    if ( XmlDiffDocument.OrderChildren( targetNode, nextSourceNode ) < 0 ) {
                                        nextSourceNode = null;
                                    }
                                }
                            }
                        }

                        // source match exists and is better
                        if ( sourceOp == XmlDiffOperation.Match ) {
                            if ( targetOp != XmlDiffOperation.Match || sourceNodesToAddCount < targetNodesToRemoveCount ) {
                                while ( targetNode != sourceClosestMatchNode ) {
                                    WalkTreeOnAddNode( diffParent, targetNode, needPositionSourceNode );
                                    needPositionSourceNode = null;
                                    targetNode = targetNode._nextSibling;
                                }
                                WalkTreeOnMatchNode( diffParent, sourceNode, targetNode, ref needPositionSourceNode );
                                goto MoveToNextPair;
                            }
                        }
                        // target match exists and is better
                        else if ( targetOp == XmlDiffOperation.Match ) {
                            while ( sourceNode != targetClosestMatchNode ) {
                                WalkTreeOnRemoveNode( diffParent, sourceNode );
                                sourceNode = sourceNode._nextSibling;
                            }
                            needPositionSourceNode = null;
                            WalkTreeOnMatchNode( diffParent, sourceNode, targetNode, ref needPositionSourceNode );
                            goto MoveToNextPair;
                        }
                        // partial match
                        else {
                            Debug.Assert( sourceOp != XmlDiffOperation.Match && targetOp != XmlDiffOperation.Match );

                            int sourceOpCost = MinimalTreeDistanceAlgo.OperationCost[ (int)sourceOp ];
                            int targetOpCost = MinimalTreeDistanceAlgo.OperationCost[ (int)targetOp ];

                            if ( sourceOpCost < targetOpCost || ( sourceOpCost == targetOpCost && sourceNodesToAddCount < targetNodesToRemoveCount ) ) {
                                while ( targetNode != sourceClosestMatchNode ) {
                                    WalkTreeOnAddNode( diffParent, targetNode, needPositionSourceNode );
                                    needPositionSourceNode = null;
                                    targetNode = targetNode._nextSibling;
                                }
                                op = sourceOp;
                            }
                            else {
                                while ( sourceNode != targetClosestMatchNode ) {
                                    WalkTreeOnRemoveNode( diffParent, sourceNode );
                                    sourceNode = sourceNode._nextSibling;
                                }
                                op = targetOp;
                            }
                        }

                        // decide whether do 'change' or 'add / delete'
                        switch ( op ) {
                            case XmlDiffOperation.ChangeElementName:
                                WalkTreeOnChangeElement( diffParent, (XmlDiffElement)sourceNode, (XmlDiffElement)targetNode, op );
                                needPositionSourceNode = null;
                                break;
                            case XmlDiffOperation.ChangeElementAttr1:
                            case XmlDiffOperation.ChangeElementAttr2:
                            case XmlDiffOperation.ChangeElementAttr3:
                            case XmlDiffOperation.ChangeElementNameAndAttr1:
                            case XmlDiffOperation.ChangeElementNameAndAttr2:
                            case XmlDiffOperation.ChangeElementNameAndAttr3:
                                if ( GoForElementChange( (XmlDiffElement)sourceNode, (XmlDiffElement)targetNode ) ) {
                                    WalkTreeOnChangeElement( diffParent, (XmlDiffElement) sourceNode, (XmlDiffElement)targetNode, op );
                                    needPositionSourceNode = null;
                                }
                                else {
                                    goto case XmlDiffOperation.Undefined;
                                }
                                break;
                            case XmlDiffOperation.ChangePI:
                            case XmlDiffOperation.ChangeER:
                            case XmlDiffOperation.ChangeCharacterData:
                            case XmlDiffOperation.ChangeXmlDeclaration:
                            case XmlDiffOperation.ChangeDTD:
                                diffParent.InsertAtEnd( new DiffgramChangeNode( sourceNode, targetNode, op, 0 ) );
                                needPositionSourceNode = null;
                                break;

                            case XmlDiffOperation.Undefined:
                                // Prefer inserts against removes
                                WalkTreeOnAddNode( diffParent, targetNode, needPositionSourceNode );
                                needPositionSourceNode = null;
                                targetNode = targetNode._nextSibling;
                                continue;
                            default:
                                Debug.Assert( false );
                                break;
                        }
                    }

                MoveToNextPair:
                    sourceNode = sourceNode._nextSibling;
                    targetNode = targetNode._nextSibling;
                }
                else { // targetNode == null
                    do {
                        WalkTreeOnRemoveNode( diffParent, sourceNode );
                        sourceNode = sourceNode._nextSibling;
                    } while ( sourceNode != null );
                }
            }
            else { // sourceNode == null
                Debug.Assert( targetNode != null );

                while ( targetNode != null ) {
                    WalkTreeOnAddNode( diffParent, targetNode, needPositionSourceNode );
                    needPositionSourceNode = null;
                    targetNode = targetNode._nextSibling;
                }
            }
            }
        }
    // Inserts the 'newChild' node. If child order is significant, the new child is
    // inserted at the end of all child nodes. If the child order is not signoficant,
    // the new node is sorted into the other child nodes.
    private void InsertChild( XmlDiffParentNode parent, XmlDiffNode newChild ) 
    {
        if ( _XmlDiff.IgnoreChildOrder ) 
        {
            XmlDiffNode curChild = parent.FirstChildNode;
			XmlDiffNode prevChild = null;

            while ( curChild != null && ( OrderChildren( curChild, newChild ) <= 0 ) ) 
            {
                prevChild = curChild;
                curChild = curChild._nextSibling;
            }
            parent.InsertChildNodeAfter( prevChild, newChild );
        }
        else
        {
            parent.InsertChildNodeAfter( _curLastChild, newChild );
            _curLastChild = newChild;
        }
    }
    // Loads child nodes of the 'parent' node
    internal void LoadChildNodes ( XmlDiffParentNode parent, XmlReader reader, bool bEmptyElement ) 
    {
        XmlDiffNode savedLastChild = _curLastChild;
        _curLastChild = null;

        // load attributes & namespace nodes
        while ( reader.MoveToNextAttribute() )
        {
            if ( reader.Prefix == "xmlns" )
            {
                if ( !_XmlDiff.IgnoreNamespaces ) 
                {
                    XmlDiffNamespace nsNode = new XmlDiffNamespace( reader.LocalName, reader.Value );
                    nsNode.ComputeHashValue( _xmlHash );
                    InsertAttributeOrNamespace( (XmlDiffElement)parent, nsNode );
                }
            }
            else if ( reader.Prefix == string.Empty  && reader.LocalName == "xmlns" )
            {
                if ( !_XmlDiff.IgnoreNamespaces ) 
                {
                    XmlDiffNamespace nsNode = new XmlDiffNamespace( string.Empty, reader.Value );
                    nsNode.ComputeHashValue( _xmlHash );
                    InsertAttributeOrNamespace( (XmlDiffElement)parent, nsNode );
                }
            }
            else
            {
                string attrValue = _XmlDiff.IgnoreWhitespace ? XmlDiff.NormalizeText( reader.Value ) : reader.Value;
                XmlDiffAttribute attr = new XmlDiffAttribute( reader.LocalName, reader.Prefix, reader.NamespaceURI, attrValue );
                attr.ComputeHashValue( _xmlHash );
                InsertAttributeOrNamespace( (XmlDiffElement)parent, attr );
            }
        }

        // empty element -> return, do not load chilren
        if ( bEmptyElement ) 
            goto End;

        int childPosition = 0;

        // load children
        if ( !reader.Read()) 
            goto End;

        do {
            // ignore whitespaces between nodes
            if ( reader.NodeType == XmlNodeType.Whitespace )
                continue;

            switch ( reader.NodeType ) 
            {
                case XmlNodeType.Element:
                {
                    bool bEmptyEl = reader.IsEmptyElement;
                    XmlDiffElement elem = new XmlDiffElement( ++childPosition, reader.LocalName, reader.Prefix, reader.NamespaceURI );

                    LoadChildNodes( elem, reader, bEmptyEl );

                    elem.ComputeHashValue( _xmlHash );
                    InsertChild( parent, 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:
                {
                    string textValue = ( _XmlDiff.IgnoreWhitespace ) ? XmlDiff.NormalizeText( reader.Value ) : reader.Value;
                    XmlDiffCharData charDataNode = new XmlDiffCharData( ++childPosition, textValue, XmlDiffNodeType.Text );
                    charDataNode.ComputeHashValue( _xmlHash );
                    InsertChild( parent, charDataNode );
                    break;
                }
                case XmlNodeType.CDATA:
                {
                    XmlDiffCharData charDataNode = new XmlDiffCharData( ++childPosition, reader.Value, XmlDiffNodeType.CDATA );
                    charDataNode.ComputeHashValue( _xmlHash );
                    InsertChild( parent, charDataNode );
                    break;
                }
                case XmlNodeType.EntityReference:
                {
                    XmlDiffER er = new XmlDiffER( ++childPosition, reader.Name );
                    er.ComputeHashValue( _xmlHash );
                    InsertChild( parent, er );
                    break;
                }
                case XmlNodeType.Comment:
                {
                    ++childPosition;
                    if ( !_XmlDiff.IgnoreComments ) 
                    {
                        XmlDiffCharData charDataNode = new XmlDiffCharData( childPosition, reader.Value, XmlDiffNodeType.Comment );
                        charDataNode.ComputeHashValue( _xmlHash );
                        InsertChild( parent, charDataNode );
                    }
                    break;
                }
                case XmlNodeType.ProcessingInstruction:
                {
                    ++childPosition;
                    if ( !_XmlDiff.IgnorePI )
                    {
                        XmlDiffPI pi = new XmlDiffPI( childPosition, reader.Name, reader.Value );
                        pi.ComputeHashValue( _xmlHash );
                        InsertChild( parent, pi );
                    }
                    break;
                }
                case XmlNodeType.SignificantWhitespace:
                {
                    if( reader.XmlSpace == XmlSpace.Preserve )
                    {
                        ++childPosition;
                        if (!_XmlDiff.IgnoreWhitespace ) 
                        {
                            XmlDiffCharData charDataNode = new XmlDiffCharData( childPosition, reader.Value, XmlDiffNodeType.SignificantWhitespace );
                            charDataNode.ComputeHashValue( _xmlHash );
                            InsertChild( parent, charDataNode );
                        }
                    }
                    break;
                }
                case XmlNodeType.XmlDeclaration:
                {
                    ++childPosition;
                    if ( !_XmlDiff.IgnoreXmlDecl ) 
                    {
                        XmlDiffXmlDeclaration xmlDecl = new XmlDiffXmlDeclaration( childPosition, XmlDiff.NormalizeXmlDeclaration( reader.Value ) );
                        xmlDecl.ComputeHashValue( _xmlHash );
						InsertChild( parent, xmlDecl );
                    }
                    break;
                }
                case XmlNodeType.EndElement:
                    goto End;

                case XmlNodeType.DocumentType:
                    childPosition++;
                    if ( !_XmlDiff.IgnoreDtd ) {
                        
                        XmlDiffDocumentType docType = new XmlDiffDocumentType( childPosition, 
                                                                               reader.Name,
                                                                               reader.GetAttribute("PUBLIC"),
                                                                               reader.GetAttribute("SYSTEM"),
                                                                               reader.Value );
                        docType.ComputeHashValue( _xmlHash );
                        InsertChild( parent, docType );
                    }
                    break;

                default:
                    Debug.Assert( false );
                    break;
            }
        } while ( reader.Read() );

    End:
        _curLastChild = savedLastChild;
    }
예제 #17
0
    private void ComputeHashXmlDiffChildren( HashAlgorithm ha, XmlDiffParentNode parent )
    {
        int childrenCount = 0;
		if ( _bIgnoreChildOrder )
		{
			ulong totalHash = 0;
            XmlDiffNode curChild = parent.FirstChildNode;
			while ( curChild != null )
			{
                Debug.Assert( !( curChild is XmlDiffAttributeOrNamespace ) );
				Debug.Assert ( curChild.HashValue != 0 );

				totalHash += curChild.HashValue;
				childrenCount++;
				curChild = curChild._nextSibling;
			}
			ha.AddULong( totalHash );
		}
		else
		{
            XmlDiffNode curChild = parent.FirstChildNode;
			while ( curChild != null )
			{
                Debug.Assert( !( curChild is XmlDiffAttributeOrNamespace ) );
				Debug.Assert ( curChild.HashValue != 0 );

				ha.AddULong( curChild.HashValue );
				childrenCount++;
				curChild = curChild._nextSibling;
			}
		}

        if ( childrenCount != 0 )
            ha.AddInt( childrenCount );
    }