Exemple #1
0
 internal static int OrderSubTrees(XmlDiffElement elem1, XmlDiffElement elem2)
 {
         var node1_1 = elem1._attributes;
         var node2_1 = elem2._attributes;
   while (node1_1 != null && node1_1.NodeType == XmlDiffNodeType.Namespace)
     node1_1 = (XmlDiffAttributeOrNamespace) node1_1._nextSibling;
   while (node2_1 != null && node2_1.NodeType == XmlDiffNodeType.Namespace)
     node2_1 = (XmlDiffAttributeOrNamespace) node2_1._nextSibling;
   for (; node1_1 != null && node2_1 != null; node2_1 = (XmlDiffAttributeOrNamespace) node2_1._nextSibling)
   {
     int num;
     if ((num = XmlDiffDocument.OrderAttributesOrNamespaces(node1_1, node2_1)) != 0)
       return num;
     node1_1 = (XmlDiffAttributeOrNamespace) node1_1._nextSibling;
   }
   if (node1_1 == node2_1)
   {
             var node1_2 = elem1.FirstChildNode;
     XmlDiffNode node2_2;
     for (node2_2 = elem2.FirstChildNode; node1_2 != null && node2_2 != null; node2_2 = node2_2._nextSibling)
     {
       int num;
       if ((num = XmlDiffDocument.OrderChildren(node1_2, node2_2)) != 0)
         return num;
       node1_2 = node1_2._nextSibling;
     }
     if (node1_2 == node2_2)
       return 0;
     return node1_2 == null ? 1 : -1;
   }
   return node1_1 == null ? 1 : -1;
 }
// 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();
        }
Exemple #3
0
        // compares the node to another one and returns true, if the nodes are identical;
        // on elements this method ignores namespace declarations
        internal override bool IsSameAs(XmlDiffNode node, XmlDiff xmlDiff)
        {
            // check node type
            Debug.Assert(node != null);
            if (node.NodeType != XmlDiffNodeType.Element)
            {
                return(false);
            }

            XmlDiffElement element = (XmlDiffElement)node;

            // check element name
            if (LocalName != element.LocalName)
            {
                return(false);
            }
            else if (!xmlDiff.IgnoreNamespaces)
            {
                if (NamespaceURI != element.NamespaceURI)
                {
                    return(false);
                }
                else if (!xmlDiff.IgnorePrefixes)
                {
                    if (Prefix != element.Prefix)
                    {
                        return(false);
                    }
                }
            }

            // ignore namespace definitions - should be first in the list of attributes
            XmlDiffAttributeOrNamespace attr1 = _attributes;

            while (attr1 != null && attr1.NodeType == XmlDiffNodeType.Namespace)
            {
                attr1 = (XmlDiffAttributeOrNamespace)attr1._nextSibling;
            }

            XmlDiffAttributeOrNamespace attr2 = _attributes;

            while (attr2 != null && attr2.NodeType == XmlDiffNodeType.Namespace)
            {
                attr2 = (XmlDiffAttributeOrNamespace)attr2._nextSibling;
            }

            // check attributes
            while (attr1 != null && attr2 != null)
            {
                if (!attr1.IsSameAs(attr2, xmlDiff))
                {
                    return(false);
                }
                attr1 = (XmlDiffAttributeOrNamespace)attr1._nextSibling;
                attr2 = (XmlDiffAttributeOrNamespace)attr2._nextSibling;
            }

            return(attr1 == null && attr2 == null);
        }
Exemple #4
0
        // compares the node to another one and returns the xmldiff operation for changing this node to the other
        internal override XmlDiffOperation GetDiffOperation(XmlDiffNode changedNode, XmlDiff xmlDiff)
        {
            Debug.Assert(changedNode != null);

            if (changedNode.NodeType != XmlDiffNodeType.Element)
            {
                return(XmlDiffOperation.Undefined);
            }

            XmlDiffElement changedElement = (XmlDiffElement)changedNode;

            // name
            bool bNameMatches = false;

            if (LocalName == changedElement.LocalName)
            {
                if (xmlDiff.IgnoreNamespaces)
                {
                    bNameMatches = true;
                }
                else
                {
                    if (NamespaceURI == changedElement.NamespaceURI &&
                        (xmlDiff.IgnorePrefixes || Prefix == changedElement.Prefix))
                    {
                        bNameMatches = true;
                    }
                }
            }

            // attributes
            if (changedElement._allAttributesHash == _allAttributesHash)
            {
                return(bNameMatches ? XmlDiffOperation.Match : XmlDiffOperation.ChangeElementName);
            }

            int n = (changedElement._attributesHashAH == _attributesHashAH ? 0 : 1) +
                    (changedElement._attributesHashIQ == _attributesHashIQ ? 0 : 1) +
                    (changedElement._attributesHashRZ == _attributesHashRZ ? 0 : 1);

            Debug.Assert((int)XmlDiffOperation.ChangeElementName + 1 == (int)XmlDiffOperation.ChangeElementAttr1);
            Debug.Assert((int)XmlDiffOperation.ChangeElementAttr1 + 1 == (int)XmlDiffOperation.ChangeElementAttr2);
            Debug.Assert((int)XmlDiffOperation.ChangeElementAttr2 + 1 == (int)XmlDiffOperation.ChangeElementAttr3);

            Debug.Assert((int)XmlDiffOperation.ChangeElementAttr3 + 1 == (int)XmlDiffOperation.ChangeElementNameAndAttr1);
            Debug.Assert((int)XmlDiffOperation.ChangeElementNameAndAttr1 + 1 == (int)XmlDiffOperation.ChangeElementNameAndAttr2);
            Debug.Assert((int)XmlDiffOperation.ChangeElementNameAndAttr2 + 1 == (int)XmlDiffOperation.ChangeElementNameAndAttr3);

            Debug.Assert(n != 0);
            if (bNameMatches)
            {
                return((XmlDiffOperation)(((int)XmlDiffOperation.ChangeElementName) + n));
            }
            else
            {
                return((XmlDiffOperation)(((int)XmlDiffOperation.ChangeElementAttr3) + n));
            }
        }
Exemple #5
0
        internal ulong ComputeHashXmlDiffElement(XmlDiffElement el)
        {
            var ha = new HashAlgorithm();

            this.HashElement(ha, el.LocalName, el.Prefix, el.NamespaceURI);
            this.ComputeHashXmlDiffAttributes(ha, el);
            this.ComputeHashXmlDiffChildren(ha, (XmlDiffParentNode)el);
            return(ha.Hash);
        }
Exemple #6
0
        internal ulong ComputeHashXmlDiffElement(XmlDiffElement el)
        {
            HashAlgorithm ha = new HashAlgorithm();

            HashElement(ha, el.LocalName, el.Prefix, el.NamespaceURI);
            ComputeHashXmlDiffAttributes(ha, el);
            ComputeHashXmlDiffChildren(ha, el);
            return(ha.Hash);
        }
Exemple #7
0
        static internal int OrderElements(XmlDiffElement elem1, XmlDiffElement elem2)
        {
            Debug.Assert(elem1 != null && elem2 != null);

            int nCompare;

            if ((nCompare = OrderStrings(elem1.LocalName, elem2.LocalName)) == 0 &&
                (nCompare = OrderStrings(elem1.NamespaceURI, elem2.NamespaceURI)) == 0)
            {
                return(OrderSubTrees(elem1, elem2));
            }
            return(nCompare);
        }
Exemple #8
0
        private void ComputeHashXmlDiffAttributes(HashAlgorithm ha, XmlDiffElement el)
        {
            var   i = 0;
            ulong u = 0;

            for (var attributeOrNamespace = el._attributes; attributeOrNamespace != null; attributeOrNamespace = (XmlDiffAttributeOrNamespace)attributeOrNamespace._nextSibling)
            {
                u += attributeOrNamespace.HashValue;
                ++i;
            }
            if (i <= 0)
            {
                return;
            }
            ha.AddULong(u);
            ha.AddInt(i);
        }
Exemple #9
0
        private void ComputeHashXmlDiffAttributes(HashAlgorithm ha, XmlDiffElement el)
        {
            int   attrCount   = 0;
            ulong attrHashAll = 0;
            XmlDiffAttributeOrNamespace curAttrOrNs = el._attributes;

            while (curAttrOrNs != null)
            {
                attrHashAll += curAttrOrNs.HashValue;
                attrCount++;
                curAttrOrNs = (XmlDiffAttributeOrNamespace)curAttrOrNs._nextSibling;
            }

            if (attrCount > 0)
            {
                ha.AddULong(attrHashAll);
                ha.AddInt(attrCount);
            }
        }
    static internal int OrderElements( XmlDiffElement elem1, XmlDiffElement elem2 ) 
    {
        Debug.Assert( elem1 != null && elem2 != null );

        int nCompare;
        if ( ( nCompare = OrderStrings( elem1.LocalName, elem2.LocalName ) ) == 0  &&
             ( nCompare = OrderStrings( elem1.NamespaceURI, elem2.NamespaceURI ) ) == 0 )
        {
            return OrderSubTrees( elem1, elem2 );
        }
        return nCompare;
    }
    static internal int OrderSubTrees( XmlDiffElement elem1, XmlDiffElement elem2 ) 
    {
        Debug.Assert( elem1 != null && elem2 != null );

        int nCompare = 0; 

        // attributes - ignore namespace nodes
        XmlDiffAttributeOrNamespace curAttr1 = elem1._attributes;
        XmlDiffAttributeOrNamespace curAttr2 = elem2._attributes;

        while ( curAttr1 != null && curAttr1.NodeType == XmlDiffNodeType.Namespace )
            curAttr1 = (XmlDiffAttributeOrNamespace)curAttr1._nextSibling;
        while ( curAttr2 != null && curAttr2.NodeType == XmlDiffNodeType.Namespace )
            curAttr2 = (XmlDiffAttributeOrNamespace)curAttr2._nextSibling;
        
        while ( curAttr1 != null && curAttr2 != null ) {
            if ( ( nCompare = OrderAttributesOrNamespaces( curAttr1, curAttr2 ) ) != 0 )
                return nCompare;
            curAttr1 = (XmlDiffAttributeOrNamespace)curAttr1._nextSibling;
            curAttr2 = (XmlDiffAttributeOrNamespace)curAttr2._nextSibling;
        }

        // children
        if ( curAttr1 == curAttr2 ) {
            XmlDiffNode curChild1 = elem1.FirstChildNode;
            XmlDiffNode curChild2 = elem2.FirstChildNode;

            while ( curChild1 != null && curChild2 != null ) 
            {
                if ( ( nCompare = OrderChildren( curChild1, curChild2 ) ) != 0 )
                    return nCompare;

                curChild1 = curChild1._nextSibling;
                curChild2 = curChild2._nextSibling;
            }

            if ( curChild1 == curChild2 ) 
                return 0;
            else if ( curChild1 ==  null ) 
                return 1; //elem2 > elem1;
            else 
                return -1; //elem1 > elem1;
        }
        else if ( curAttr1 == null )
            return 1; //elem2 > elem1;
        else {
            return -1; //elem1 > elem1;
        }
    }
Exemple #12
0
        static internal int OrderSubTrees(XmlDiffElement elem1, XmlDiffElement elem2)
        {
            Debug.Assert(elem1 != null && elem2 != null);

            int nCompare = 0;

            // attributes - ignore namespace nodes
            XmlDiffAttributeOrNamespace curAttr1 = elem1._attributes;
            XmlDiffAttributeOrNamespace curAttr2 = elem2._attributes;

            while (curAttr1 != null && curAttr1.NodeType == XmlDiffNodeType.Namespace)
            {
                curAttr1 = (XmlDiffAttributeOrNamespace)curAttr1._nextSibling;
            }
            while (curAttr2 != null && curAttr2.NodeType == XmlDiffNodeType.Namespace)
            {
                curAttr2 = (XmlDiffAttributeOrNamespace)curAttr2._nextSibling;
            }

            while (curAttr1 != null && curAttr2 != null)
            {
                if ((nCompare = OrderAttributesOrNamespaces(curAttr1, curAttr2)) != 0)
                {
                    return(nCompare);
                }
                curAttr1 = (XmlDiffAttributeOrNamespace)curAttr1._nextSibling;
                curAttr2 = (XmlDiffAttributeOrNamespace)curAttr2._nextSibling;
            }

            // children
            if (curAttr1 == curAttr2)
            {
                XmlDiffNode curChild1 = elem1.FirstChildNode;
                XmlDiffNode curChild2 = elem2.FirstChildNode;

                while (curChild1 != null && curChild2 != null)
                {
                    if ((nCompare = OrderChildren(curChild1, curChild2)) != 0)
                    {
                        return(nCompare);
                    }

                    curChild1 = curChild1._nextSibling;
                    curChild2 = curChild2._nextSibling;
                }

                if (curChild1 == curChild2)
                {
                    return(0);
                }
                else if (curChild1 == null)
                {
                    return(1); //elem2 > elem1;
                }
                else
                {
                    return(-1); //elem1 > elem1;
                }
            }
            else if (curAttr1 == null)
            {
                return(1); //elem2 > elem1;
            }
            else
            {
                return(-1); //elem1 > elem1;
            }
        }
Exemple #13
0
        internal XmlDiffNode LoadNode(XmlNode node, ref int childPosition)
        {
            switch (node.NodeType)
            {
            case XmlNodeType.Element:
                XmlDiffElement elem = new XmlDiffElement(++childPosition, node.LocalName, node.Prefix, node.NamespaceURI);
                LoadChildNodes(elem, node);
                elem.ComputeHashValue(_xmlHash);
                return(elem);

            case XmlNodeType.Attribute:
                Debug.Assert(false, "Attributes cannot be loaded by this method.");
                return(null);

            case XmlNodeType.Text:
                string          textValue = (_XmlDiff.IgnoreWhitespace) ? XmlDiff.NormalizeText(node.Value) : node.Value;
                XmlDiffCharData text      = new XmlDiffCharData(++childPosition, textValue, XmlDiffNodeType.Text);
                text.ComputeHashValue(_xmlHash);
                return(text);

            case XmlNodeType.CDATA:
                XmlDiffCharData cdata = new XmlDiffCharData(++childPosition, node.Value, XmlDiffNodeType.CDATA);
                cdata.ComputeHashValue(_xmlHash);
                return(cdata);

            case XmlNodeType.EntityReference:
                XmlDiffER er = new XmlDiffER(++childPosition, node.Name);
                er.ComputeHashValue(_xmlHash);
                return(er);

            case XmlNodeType.Comment:
                ++childPosition;
                if (_XmlDiff.IgnoreComments)
                {
                    return(null);
                }

                XmlDiffCharData comment = new XmlDiffCharData(childPosition, node.Value, XmlDiffNodeType.Comment);
                comment.ComputeHashValue(_xmlHash);
                return(comment);

            case XmlNodeType.ProcessingInstruction:
                ++childPosition;
                if (_XmlDiff.IgnorePI)
                {
                    return(null);
                }

                XmlDiffPI pi = new XmlDiffPI(childPosition, node.Name, node.Value);
                pi.ComputeHashValue(_xmlHash);
                return(pi);

            case XmlNodeType.SignificantWhitespace:
                ++childPosition;
                if (_XmlDiff.IgnoreWhitespace)
                {
                    return(null);
                }
                XmlDiffCharData ws = new XmlDiffCharData(childPosition, node.Value, XmlDiffNodeType.SignificantWhitespace);
                ws.ComputeHashValue(_xmlHash);
                return(ws);

            case XmlNodeType.XmlDeclaration:
                ++childPosition;
                if (_XmlDiff.IgnoreXmlDecl)
                {
                    return(null);
                }
                XmlDiffXmlDeclaration xmlDecl = new XmlDiffXmlDeclaration(childPosition, XmlDiff.NormalizeXmlDeclaration(node.Value));
                xmlDecl.ComputeHashValue(_xmlHash);
                return(xmlDecl);

            case XmlNodeType.EndElement:
                return(null);

            case XmlNodeType.DocumentType:
                childPosition++;
                if (_XmlDiff.IgnoreDtd)
                {
                    return(null);
                }

                XmlDocumentType     docType     = (XmlDocumentType)node;
                XmlDiffDocumentType diffDocType = new XmlDiffDocumentType(childPosition, docType.Name, docType.PublicId, docType.SystemId, docType.InternalSubset);
                diffDocType.ComputeHashValue(_xmlHash);
                return(diffDocType);

            default:
                Debug.Assert(false);
                return(null);
            }
        }
Exemple #14
0
 // Inserts an attribute or namespace node. The new node is sorted into the other attributes/namespace nodes.
 private void InsertAttributeOrNamespace(XmlDiffElement element, XmlDiffAttributeOrNamespace newAttrOrNs)
 {
     element.InsertAttributeOrNamespace(newAttrOrNs);
 }
Exemple #15
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;
    }
Exemple #16
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;
        }
 private void GenerateAddDiffgramForAttributes( DiffgramParentOperation diffgramParent, XmlDiffElement targetElement )
 {
     XmlDiffAttributeOrNamespace attr = targetElement._attributes;
     while ( attr != null )
     {
     diffgramParent.InsertAtBeginning( new DiffgramAddNode( attr, 0 ) );
     attr = (XmlDiffAttributeOrNamespace)attr._nextSibling;
     }
 }
        private void GenerateChangeDiffgramForAttributes( DiffgramParentOperation diffgramParent, 
            XmlDiffElement sourceElement,
            XmlDiffElement targetElement)
        {
            XmlDiffAttributeOrNamespace sourceAttr = sourceElement._attributes;
            XmlDiffAttributeOrNamespace targetAttr = targetElement._attributes;
            int nCompare;
            ulong opid;

            while ( sourceAttr != null && targetAttr != null )
            {
            opid = 0;

            if ( sourceAttr.NodeType == targetAttr.NodeType )
            {
                if ( sourceAttr.NodeType == XmlDiffNodeType.Attribute )
                {
                    if ( (nCompare = XmlDiffDocument.OrderStrings( sourceAttr.LocalName, targetAttr.LocalName )) == 0 )
                    {
                        if ( _xmlDiff.IgnoreNamespaces )
                        {
                            if ( XmlDiffDocument.OrderStrings( sourceAttr.Value, targetAttr.Value ) == 0 )
                            {
                                // attributes match
                                goto Next;
                            }
                        }
                        else
                        {
                            if ( XmlDiffDocument.OrderStrings( sourceAttr.NamespaceURI, targetAttr.NamespaceURI ) == 0  &&
                                 (_xmlDiff.IgnorePrefixes || XmlDiffDocument.OrderStrings( sourceAttr.Prefix, targetAttr.Prefix )  == 0 ) &&
                                XmlDiffDocument.OrderStrings( sourceAttr.Value, targetAttr.Value ) == 0 )
                            {
                                // attributes match
                                goto Next;
                            }
                        }

                        diffgramParent.InsertAtBeginning( new DiffgramChangeNode( sourceAttr, targetAttr, XmlDiffOperation.ChangeAttr, 0 ) );
                        goto Next;
                    }

                    goto AddRemove;
                }
                else // sourceAttr.NodeType != XmlDiffNodeType.Attribute
                {
                    if ( _xmlDiff.IgnorePrefixes ) {
                        if ( ( nCompare = XmlDiffDocument.OrderStrings( sourceAttr.NamespaceURI, targetAttr.NamespaceURI ) ) == 0 )
                            goto Next;
                        else
                            goto AddRemove;
                    }
                    else if ( ( nCompare = XmlDiffDocument.OrderStrings( sourceAttr.Prefix, targetAttr.Prefix ) ) == 0 ) {
                        if ( ( nCompare = XmlDiffDocument.OrderStrings( sourceAttr.NamespaceURI, targetAttr.NamespaceURI ) ) == 0 )
                            goto Next;
                        else {
                            // change of namespace
                            opid = GetNamespaceChangeOpid( sourceAttr.NamespaceURI, sourceAttr.Prefix,
                                                        targetAttr.NamespaceURI, targetAttr.Prefix );
                            goto AddRemoveBoth;
                        }
                    }
                    else {
                        if ( ( nCompare = XmlDiffDocument.OrderStrings( sourceAttr.NamespaceURI, targetAttr.NamespaceURI ) ) == 0 ) {
                            // change of prefix
                            opid = GetNamespaceChangeOpid( sourceAttr.NamespaceURI, sourceAttr.Prefix,
                                                        targetAttr.NamespaceURI, targetAttr.Prefix );
                            goto AddRemoveBoth;
                        }
                        else {
                            goto AddRemove;
                        }
                    }
                }
            }
            else // ( sourceAttr.NodeType != targetAttr.NodeType )
            {
                if ( sourceAttr.NodeType == XmlDiffNodeType.Namespace )
                    goto RemoveSource;
                else
                    goto AddTarget;
            }

            Next:
            sourceAttr = (XmlDiffAttributeOrNamespace)sourceAttr._nextSibling;
            targetAttr = (XmlDiffAttributeOrNamespace)targetAttr._nextSibling;
            continue;

            AddRemove:
            if ( nCompare == -1 )
                goto RemoveSource;
            else
            {
                Debug.Assert( nCompare == 1 );
                goto AddTarget;
            }

            AddRemoveBoth:
            if ( !diffgramParent.MergeRemoveAttributeAtBeginning( sourceAttr ) )
                diffgramParent.InsertAtBeginning( new DiffgramRemoveNode( sourceAttr, true, opid ) );
            sourceAttr = (XmlDiffAttributeOrNamespace)sourceAttr._nextSibling;

            diffgramParent.InsertAtBeginning( new DiffgramAddNode( targetAttr, opid ) );
            targetAttr = (XmlDiffAttributeOrNamespace)targetAttr._nextSibling;
            continue;

            RemoveSource:
            if ( !diffgramParent.MergeRemoveAttributeAtBeginning( sourceAttr ) )
                diffgramParent.InsertAtBeginning( new DiffgramRemoveNode( sourceAttr, true, opid ) );
            sourceAttr = (XmlDiffAttributeOrNamespace)sourceAttr._nextSibling;
            continue;

            AddTarget:
            diffgramParent.InsertAtBeginning( new DiffgramAddNode( targetAttr, opid ) );
            targetAttr = (XmlDiffAttributeOrNamespace)targetAttr._nextSibling;
            continue;
            }

            while ( sourceAttr != null )
            {
            if ( !diffgramParent.MergeRemoveAttributeAtBeginning( sourceAttr ) )
                diffgramParent.InsertAtBeginning( new DiffgramRemoveNode( sourceAttr, true, 0 ) );
            sourceAttr = (XmlDiffAttributeOrNamespace)sourceAttr._nextSibling;
            }

            while ( targetAttr != null )
            {
            diffgramParent.InsertAtBeginning( new DiffgramAddNode( targetAttr, 0 ) );
            targetAttr = (XmlDiffAttributeOrNamespace)targetAttr._nextSibling;
            }
        }
    internal XmlDiffNode LoadNode( XmlNode node, ref int childPosition ) {
        switch ( node.NodeType ) 
        {
            case XmlNodeType.Element:
                XmlDiffElement elem = new XmlDiffElement( ++childPosition, node.LocalName, node.Prefix, node.NamespaceURI );
                LoadChildNodes( elem, node );
                elem.ComputeHashValue( _xmlHash );
                return elem;

            case XmlNodeType.Attribute:
                Debug.Assert( false, "Attributes cannot be loaded by this method." );
                return null;

            case XmlNodeType.Text:
                string textValue = ( _XmlDiff.IgnoreWhitespace ) ? XmlDiff.NormalizeText( node.Value ) : node.Value;
                XmlDiffCharData text = new XmlDiffCharData( ++childPosition, textValue, XmlDiffNodeType.Text );
                text.ComputeHashValue( _xmlHash );
                return text;

            case XmlNodeType.CDATA:
                XmlDiffCharData cdata = new XmlDiffCharData( ++childPosition, node.Value, XmlDiffNodeType.CDATA );
                cdata.ComputeHashValue( _xmlHash );
                return cdata;

            case XmlNodeType.EntityReference:
                XmlDiffER er = new XmlDiffER( ++childPosition, node.Name );
                er.ComputeHashValue( _xmlHash );
                return er;

            case XmlNodeType.Comment:
                ++childPosition;
                if ( _XmlDiff.IgnoreComments ) 
                    return null;

                XmlDiffCharData comment = new XmlDiffCharData( childPosition, node.Value, XmlDiffNodeType.Comment );
                comment.ComputeHashValue( _xmlHash );
                return comment;

            case XmlNodeType.ProcessingInstruction:
                ++childPosition;
                if ( _XmlDiff.IgnorePI )
                    return null;

                XmlDiffPI pi = new XmlDiffPI( childPosition, node.Name, node.Value );
                pi.ComputeHashValue( _xmlHash );
                return pi;

            case XmlNodeType.SignificantWhitespace:
                ++childPosition;
                if ( _XmlDiff.IgnoreWhitespace ) 
                    return null;
                XmlDiffCharData ws = new XmlDiffCharData( childPosition, node.Value, XmlDiffNodeType.SignificantWhitespace );
                ws.ComputeHashValue( _xmlHash );
                return ws;

            case XmlNodeType.XmlDeclaration:
                ++childPosition;
                if ( _XmlDiff.IgnoreXmlDecl ) 
                    return null;
                XmlDiffXmlDeclaration xmlDecl = new XmlDiffXmlDeclaration( childPosition, XmlDiff.NormalizeXmlDeclaration( node.Value ) );
                xmlDecl.ComputeHashValue( _xmlHash );
				return xmlDecl;

            case XmlNodeType.EndElement:
                return null;

            case XmlNodeType.DocumentType:
                childPosition++;
                if ( _XmlDiff.IgnoreDtd )
                    return null;

                XmlDocumentType docType = (XmlDocumentType)node;
                XmlDiffDocumentType diffDocType = new XmlDiffDocumentType( childPosition, docType.Name, docType.PublicId, docType.SystemId, docType.InternalSubset );
                diffDocType.ComputeHashValue( _xmlHash );
                return diffDocType;

            default:
                Debug.Assert( false );
                return null;
        }
    }
        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 );
        }
 internal ulong ComputeHashXmlDiffElement( XmlDiffElement el )
 {
     HashAlgorithm ha = new HashAlgorithm();
     HashElement( ha, el.LocalName, el.Prefix, el.NamespaceURI );
     ComputeHashXmlDiffAttributes( ha, el );
     ComputeHashXmlDiffChildren( ha, el );
     return ha.Hash;
 }
    private void ComputeHashXmlDiffAttributes( HashAlgorithm ha, XmlDiffElement el )
    {
        int attrCount = 0;
        ulong attrHashAll = 0;
        XmlDiffAttributeOrNamespace curAttrOrNs = el._attributes;
        while ( curAttrOrNs != null )
        {
            attrHashAll += curAttrOrNs.HashValue;
            attrCount++;
            curAttrOrNs = (XmlDiffAttributeOrNamespace)curAttrOrNs._nextSibling;
        }

        if ( attrCount > 0 ) 
        {
            ha.AddULong( attrHashAll );
            ha.AddInt( attrCount );
        }
    }
Exemple #23
0
 internal XmlDiffNode LoadNode(XmlNode node, ref int childPosition)
 {
   switch (node.NodeType)
   {
     case XmlNodeType.Element:
                 var xmlDiffElement = new XmlDiffElement(++childPosition, node.LocalName, node.Prefix, node.NamespaceURI);
       this.LoadChildNodes((XmlDiffParentNode) xmlDiffElement, node);
       xmlDiffElement.ComputeHashValue(this._xmlHash);
       return (XmlDiffNode) xmlDiffElement;
     case XmlNodeType.Attribute:
       return (XmlDiffNode) null;
     case XmlNodeType.Text:
       var str = this._XmlDiff.IgnoreWhitespace ? XmlDiff.NormalizeText(node.Value) : node.Value;
                 var xmlDiffCharData1 = new XmlDiffCharData(++childPosition, str, XmlDiffNodeType.Text);
       xmlDiffCharData1.ComputeHashValue(this._xmlHash);
       return (XmlDiffNode) xmlDiffCharData1;
     case XmlNodeType.CDATA:
                 var xmlDiffCharData2 = new XmlDiffCharData(++childPosition, node.Value, XmlDiffNodeType.CDATA);
       xmlDiffCharData2.ComputeHashValue(this._xmlHash);
       return (XmlDiffNode) xmlDiffCharData2;
     case XmlNodeType.EntityReference:
                 var xmlDiffEr = new XmlDiffER(++childPosition, node.Name);
       xmlDiffEr.ComputeHashValue(this._xmlHash);
       return (XmlDiffNode) xmlDiffEr;
     case XmlNodeType.ProcessingInstruction:
       ++childPosition;
       if (this._XmlDiff.IgnorePI)
         return (XmlDiffNode) null;
                 var xmlDiffPi = new XmlDiffPI(childPosition, node.Name, node.Value);
       xmlDiffPi.ComputeHashValue(this._xmlHash);
       return (XmlDiffNode) xmlDiffPi;
     case XmlNodeType.Comment:
       ++childPosition;
       if (this._XmlDiff.IgnoreComments)
         return (XmlDiffNode) null;
                 var xmlDiffCharData3 = new XmlDiffCharData(childPosition, node.Value, XmlDiffNodeType.Comment);
       xmlDiffCharData3.ComputeHashValue(this._xmlHash);
       return (XmlDiffNode) xmlDiffCharData3;
     case XmlNodeType.DocumentType:
       ++childPosition;
       if (this._XmlDiff.IgnoreDtd)
         return (XmlDiffNode) null;
                 var xmlDocumentType = (XmlDocumentType) node;
                 var diffDocumentType = new XmlDiffDocumentType(childPosition, xmlDocumentType.Name, xmlDocumentType.PublicId, xmlDocumentType.SystemId, xmlDocumentType.InternalSubset);
       diffDocumentType.ComputeHashValue(this._xmlHash);
       return (XmlDiffNode) diffDocumentType;
     case XmlNodeType.SignificantWhitespace:
       ++childPosition;
       if (this._XmlDiff.IgnoreWhitespace)
         return (XmlDiffNode) null;
                 var xmlDiffCharData4 = new XmlDiffCharData(childPosition, node.Value, XmlDiffNodeType.SignificantWhitespace);
       xmlDiffCharData4.ComputeHashValue(this._xmlHash);
       return (XmlDiffNode) xmlDiffCharData4;
     case XmlNodeType.EndElement:
       return (XmlDiffNode) null;
     case XmlNodeType.XmlDeclaration:
       ++childPosition;
       if (this._XmlDiff.IgnoreXmlDecl)
         return (XmlDiffNode) null;
                 var diffXmlDeclaration = new XmlDiffXmlDeclaration(childPosition, XmlDiff.NormalizeXmlDeclaration(node.Value));
       diffXmlDeclaration.ComputeHashValue(this._xmlHash);
       return (XmlDiffNode) diffXmlDeclaration;
     default:
       return (XmlDiffNode) null;
   }
 }
 // Inserts an attribute or namespace node. The new node is sorted into the other attributes/namespace nodes.
 private void InsertAttributeOrNamespace( XmlDiffElement element, XmlDiffAttributeOrNamespace newAttrOrNs ) 
 {
     element.InsertAttributeOrNamespace( newAttrOrNs );
 }
        // returns true if the two elements have at least 50% in common (common name & attributes)
        private bool GoForElementChange( XmlDiffElement sourceElement, XmlDiffElement targetElement )
        {
            int identicalAttrCount = 0;
            int addedAttrCount = 0;
            int removedAttrCount = 0;
            int changedAttrCount = 0;
            bool bNameChange;

            bNameChange = ( sourceElement.LocalName != targetElement.LocalName );

            XmlDiffAttributeOrNamespace sourceAttr = sourceElement._attributes;
            XmlDiffAttributeOrNamespace targetAttr = targetElement._attributes;
            while ( sourceAttr != null && targetAttr != null ) {
            if ( sourceAttr.LocalName == targetAttr.LocalName ) {
                if ( ( _xmlDiff.IgnorePrefixes || _xmlDiff.IgnoreNamespaces || sourceAttr.Prefix == targetAttr.Prefix ) &&
                     ( _xmlDiff.IgnoreNamespaces || sourceAttr.NamespaceURI == targetAttr.NamespaceURI ) ) {
                    if ( sourceAttr.Value == targetAttr.Value ) {
                        identicalAttrCount++;
                    }
                    else {
                        changedAttrCount++;
                    }
                }
                else {
                    changedAttrCount++;
                }
                sourceAttr = (XmlDiffAttributeOrNamespace)sourceAttr._nextSibling;
                targetAttr = (XmlDiffAttributeOrNamespace)targetAttr._nextSibling;
            }
            else {
                int compare = XmlDiffDocument.OrderAttributesOrNamespaces( sourceAttr, targetAttr );
                if ( compare < 0 ) {
                    removedAttrCount++;
                    sourceAttr = (XmlDiffAttributeOrNamespace)sourceAttr._nextSibling;
                }
                else {
                    addedAttrCount++;
                    targetAttr = (XmlDiffAttributeOrNamespace)targetAttr._nextSibling;
                }
            }
            }

            while ( sourceAttr != null ) {
            removedAttrCount++;
            sourceAttr = (XmlDiffAttributeOrNamespace)sourceAttr._nextSibling;
            }

            while ( targetAttr != null ) {
            addedAttrCount++;
            targetAttr = (XmlDiffAttributeOrNamespace)targetAttr._nextSibling;
            }

            if ( bNameChange ) {
            // total number of changes is less than 50%
            if ( removedAttrCount + addedAttrCount + changedAttrCount <= identicalAttrCount )
                return true;

            return false;
            }
            else {
            // only added
            if ( removedAttrCount + changedAttrCount == 0 )
                return true;

            // only removed
            if ( addedAttrCount + changedAttrCount == 0 )
                return true;

            // no removed or added:
            if ( removedAttrCount + addedAttrCount == 0 ) {
                return true;
            }

            // total number of changes is less than 75% - or -
            // no other sibling node
            if ( removedAttrCount + addedAttrCount + changedAttrCount <= identicalAttrCount * 3 ||
                sourceElement._nextSibling == null )
                return true;

            return false;
            }
        }
// Methods
        internal override void WriteTo(XmlWriter xmlWriter, XmlDiff xmlDiff)
        {
            xmlWriter.WriteStartElement(XmlDiff.Prefix, "add", XmlDiff.NamespaceUri);

            switch (_targetNode.NodeType)
            {
            case XmlDiffNodeType.Element:
            {
                xmlWriter.WriteAttributeString("type", ((int)XmlNodeType.Element).ToString());

                XmlDiffElement el = _targetNode as XmlDiffElement;
                xmlWriter.WriteAttributeString("name", el.LocalName);
                if (el.NamespaceURI != string.Empty)
                {
                    xmlWriter.WriteAttributeString("ns", el.NamespaceURI);
                }
                if (el.Prefix != string.Empty)
                {
                    xmlWriter.WriteAttributeString("prefix", el.Prefix);
                }
                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }

                WriteChildrenTo(xmlWriter, xmlDiff);
                break;
            }

            case XmlDiffNodeType.Attribute:
            {
                xmlWriter.WriteAttributeString("type", ((int)XmlNodeType.Attribute).ToString());

                XmlDiffAttribute at = _targetNode as XmlDiffAttribute;
                xmlWriter.WriteAttributeString("name", at.LocalName);
                if (at.NamespaceURI != string.Empty)
                {
                    xmlWriter.WriteAttributeString("ns", at.NamespaceURI);
                }
                if (at.Prefix != string.Empty)
                {
                    xmlWriter.WriteAttributeString("prefix", at.Prefix);
                }
                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }
                xmlWriter.WriteString(at.Value);
                break;
            }

            case XmlDiffNodeType.Namespace:
            {
                xmlWriter.WriteAttributeString("type", ((int)XmlNodeType.Attribute).ToString());

                XmlDiffNamespace ns = _targetNode as XmlDiffNamespace;
                if (ns.Prefix != string.Empty)
                {
                    xmlWriter.WriteAttributeString("prefix", "xmlns");
                    xmlWriter.WriteAttributeString("name", ns.Prefix);
                }
                else
                {
                    xmlWriter.WriteAttributeString("name", "xmlns");
                }
                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }

                xmlWriter.WriteString(ns.NamespaceURI);
                break;
            }

            case XmlDiffNodeType.CDATA:
            {
                Debug.Assert(false, "CDATA nodes should be added with DiffgramAddSubtrees class.");

                xmlWriter.WriteAttributeString("type", ((int)_targetNode.NodeType).ToString());

                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }
                xmlWriter.WriteCData((_targetNode as XmlDiffCharData).Value);
                break;
            }

            case XmlDiffNodeType.Comment:
            {
                Debug.Assert(false, "Comment nodes should be added with DiffgramAddSubtrees class.");

                xmlWriter.WriteAttributeString("type", ((int)_targetNode.NodeType).ToString());

                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }
                xmlWriter.WriteComment((_targetNode as XmlDiffCharData).Value);
                break;
            }

            case XmlDiffNodeType.Text:
            {
                Debug.Assert(false, "Text nodes should be added with DiffgramAddSubtrees class.");

                xmlWriter.WriteAttributeString("type", ((int)_targetNode.NodeType).ToString());

                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }
                xmlWriter.WriteString((_targetNode as XmlDiffCharData).Value);
                break;
            }

            case XmlDiffNodeType.ProcessingInstruction:
            {
                Debug.Assert(false, "Processing instruction nodes should be added with DiffgramAddSubtrees class.");

                xmlWriter.WriteAttributeString("type", ((int)_targetNode.NodeType).ToString());

                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }
                XmlDiffPI pi = _targetNode as XmlDiffPI;
                xmlWriter.WriteProcessingInstruction(pi.Name, pi.Value);
                break;
            }

            case XmlDiffNodeType.EntityReference:
            {
                xmlWriter.WriteAttributeString("type", ((int)XmlNodeType.EntityReference).ToString());

                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }

                xmlWriter.WriteAttributeString("name", ((XmlDiffER)_targetNode).Name);
                break;
            }

            case XmlDiffNodeType.SignificantWhitespace:
            {
                Debug.Assert(false, "Significant whitespace nodes should be added with DiffgramAddSubtrees class.");

                xmlWriter.WriteAttributeString("type", ((int)_targetNode.NodeType).ToString());

                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }
                xmlWriter.WriteString(((XmlDiffCharData)_targetNode).Value);
                break;
            }

            case XmlDiffNodeType.XmlDeclaration:
            {
                xmlWriter.WriteAttributeString("type", ((int)XmlNodeType.XmlDeclaration).ToString());

                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }
                xmlWriter.WriteString(((XmlDiffXmlDeclaration)_targetNode).Value);
                break;
            }

            case XmlDiffNodeType.DocumentType:
            {
                xmlWriter.WriteAttributeString("type", ((int)XmlNodeType.DocumentType).ToString());

                XmlDiffDocumentType docType = (XmlDiffDocumentType)_targetNode;

                if (_operationID != 0)
                {
                    xmlWriter.WriteAttributeString("opid", _operationID.ToString());
                }
                xmlWriter.WriteAttributeString("name", docType.Name);
                if (docType.PublicId != string.Empty)
                {
                    xmlWriter.WriteAttributeString("publicId", docType.PublicId);
                }
                if (docType.SystemId != string.Empty)
                {
                    xmlWriter.WriteAttributeString("systemId", docType.SystemId);
                }
                if (docType.Subset != string.Empty)
                {
                    xmlWriter.WriteCData(docType.Subset);
                }
                break;
            }

            default:
                Debug.Assert(false);
                break;
            }

            xmlWriter.WriteEndElement();
        }
Exemple #27
0
 internal static int OrderElements(XmlDiffElement elem1, XmlDiffElement elem2)
 {
   int num;
   return (num = XmlDiffDocument.OrderStrings(elem1.LocalName, elem2.LocalName)) == 0 && (num = XmlDiffDocument.OrderStrings(elem1.NamespaceURI, elem2.NamespaceURI)) == 0 ? XmlDiffDocument.OrderSubTrees(elem1, elem2) : num;
 }
// Methods
        internal override void WriteTo(XmlWriter xmlWriter, XmlDiff xmlDiff)
        {
            xmlWriter.WriteStartElement(XmlDiff.Prefix, "change", XmlDiff.NamespaceUri);
            xmlWriter.WriteAttributeString("match", _sourceNode.GetRelativeAddress());
            if (_operationID != 0)
            {
                xmlWriter.WriteAttributeString("opid", _operationID.ToString());
            }

            switch (_op)
            {
            case XmlDiffOperation.ChangeAttr:
            {
                XmlDiffAttribute sourceAttr = (XmlDiffAttribute)_sourceNode;
                XmlDiffAttribute targetAttr = (XmlDiffAttribute)_targetNode;

                if (sourceAttr.Prefix != targetAttr.Prefix && !xmlDiff.IgnorePrefixes && !xmlDiff.IgnoreNamespaces)
                {
                    xmlWriter.WriteAttributeString("prefix", targetAttr.Prefix);
                }
                if (sourceAttr.NamespaceURI != targetAttr.NamespaceURI && !xmlDiff.IgnoreNamespaces)
                {
                    xmlWriter.WriteAttributeString("ns", targetAttr.NamespaceURI);
                }
                xmlWriter.WriteString(targetAttr.Value);
                break;
            }

            case XmlDiffOperation.ChangeElementName:
            {
                XmlDiffElement sourceEl = (XmlDiffElement)_sourceNode;
                XmlDiffElement targetEl = (XmlDiffElement)_targetNode;

                if (sourceEl.LocalName != targetEl.LocalName)
                {
                    xmlWriter.WriteAttributeString("name", targetEl.LocalName);
                }
                if (sourceEl.Prefix != targetEl.Prefix && !xmlDiff.IgnorePrefixes && !xmlDiff.IgnoreNamespaces)
                {
                    xmlWriter.WriteAttributeString("prefix", targetEl.Prefix);
                }
                if (sourceEl.NamespaceURI != targetEl.NamespaceURI && !xmlDiff.IgnoreNamespaces)
                {
                    xmlWriter.WriteAttributeString("ns", targetEl.NamespaceURI);
                }

                WriteChildrenTo(xmlWriter, xmlDiff);

                break;
            }

            case XmlDiffOperation.ChangePI:
            {
                XmlDiffPI sourcePi = (XmlDiffPI)_sourceNode;
                XmlDiffPI targetPi = (XmlDiffPI)_targetNode;

                if (sourcePi.Value == targetPi.Value)
                {
                    Debug.Assert(sourcePi.Name != targetPi.Name);
                    xmlWriter.WriteAttributeString("name", targetPi.Name);
                }
                else
                {
                    xmlWriter.WriteProcessingInstruction(targetPi.Name, targetPi.Value);
                }
                break;
            }

            case XmlDiffOperation.ChangeCharacterData:
            {
                XmlDiffCharData chd = (XmlDiffCharData)_targetNode;
                switch (_targetNode.NodeType)
                {
                case XmlDiffNodeType.Text:
                case XmlDiffNodeType.SignificantWhitespace:
                    xmlWriter.WriteString(chd.Value);
                    break;

                case XmlDiffNodeType.Comment:
                    xmlWriter.WriteComment(chd.Value);
                    break;

                case XmlDiffNodeType.CDATA:
                    xmlWriter.WriteCData(chd.Value);
                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
                break;
            }

            case XmlDiffOperation.ChangeER:
            {
                xmlWriter.WriteAttributeString("name", ((XmlDiffER)_targetNode).Name);
                break;
            }

            case XmlDiffOperation.ChangeXmlDeclaration:
            {
                xmlWriter.WriteString(((XmlDiffXmlDeclaration)_targetNode).Value);
                break;
            }

            case XmlDiffOperation.ChangeDTD:
            {
                XmlDiffDocumentType sourceDtd = (XmlDiffDocumentType)_sourceNode;
                XmlDiffDocumentType targetDtd = (XmlDiffDocumentType)_targetNode;

                if (sourceDtd.Name != targetDtd.Name)
                {
                    xmlWriter.WriteAttributeString("name", targetDtd.Name);
                }
                if (sourceDtd.SystemId != targetDtd.SystemId)
                {
                    xmlWriter.WriteAttributeString("systemId", targetDtd.SystemId);
                }
                if (sourceDtd.PublicId != targetDtd.PublicId)
                {
                    xmlWriter.WriteAttributeString("publicId", targetDtd.PublicId);
                }
                if (sourceDtd.Subset != targetDtd.Subset)
                {
                    xmlWriter.WriteCData(targetDtd.Subset);
                }
                break;
            }

            default:
                Debug.Assert(false);
                break;
            }

            xmlWriter.WriteEndElement();
        }
    // 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;
    }