private static string InsertXmlComments()

in src/FabActUtil/Generator/XmlSerializationUtility.cs [96:185]


        private static string InsertXmlComments(string contentWithComments, string contentWithoutComments)
        {
            var commentNodes = XDocument.Parse(contentWithComments).DescendantNodes().OfType<XComment>();
            var xdoc = XDocument.Parse(contentWithoutComments);

            // if there are no comments to insert, just return the contentsWithoutComments
            if (!commentNodes.Any())
            {
                return contentWithoutComments;
            }

            foreach (var commentNode in commentNodes)
            {
                var newComment = new XComment(commentNode.Value);

                // Handle comments at beginning and end of xml
                if (commentNode.Parent == null)
                {
                    // Handle comments at beginning of xml
                    if (commentNode.PreviousNode == null && commentNode.NextNode != null)
                    {
                        xdoc.Root.AddBeforeSelf(newComment);
                    }

                    // Handle comments at end of xml
                    if (commentNode.NextNode == null && commentNode.PreviousNode != null)
                    {
                        xdoc.Root.AddAfterSelf(newComment);
                    }
                }
                else
                {
                    // If Parent node of comment is not found in new xml, then dont add this comment.
                    var parent = xdoc.Descendants(commentNode.Parent.Name).FirstOrDefault();
                    if (parent != null)
                    {
                        var hadPrevious = commentNode.ElementsBeforeSelf().Any();
                        var hadNext = commentNode.ElementsAfterSelf().Any();

                        if (!hadNext)
                        {
                            // Handles if comment is last child of parent.
                            // Also handles if comment had no siblings i.e. node only has this comment.
                            parent.Add(newComment);
                        }
                        else if (!hadPrevious)
                        {
                            // Handles if comment is first child of parent.
                            parent.AddFirst(newComment);
                        }
                        else if (hadPrevious && hadNext)
                        {
                            // Handles if comment had both Previous and Next siblings.

                            // If PreviousNode of comment is in new Xml, add newComment after PreviousNode
                            // If PreviousNode is not in new xml and NextNode is in newXml, add newComment before NextNode.
                            // If both PreviousNode and NextNode is not in new xml skip it.
                            var previousInOriginal = commentNode.ElementsBeforeSelf().Last();
                            var nextInOriginal = commentNode.ElementsAfterSelf().First();

                            // Find matching Previous and Next siblings in new xml. Siblings must match in attributes as well.
                            var previous = FindNodeInXDocument(xdoc, previousInOriginal);
                            var next = FindNodeInXDocument(xdoc, nextInOriginal);

                            if (previous != null)
                            {
                                previous.AddAfterSelf(newComment);
                            }
                            else if (next != null)
                            {
                                next.AddBeforeSelf(newComment);
                            }
                        }
                    }
                }
            }

            // Use XmlWriterSettings same as used in serialization to keep changes to existing files to minimal.
            var stringBuilder = new StringBuilder();
            using (var memoryStream = new MemoryStream())
            {
                using (var xmlWriter = XmlWriter.Create(memoryStream, XmlSerializationUtility.GetXmlWriterSettings()))
                {
                    xdoc.Save(xmlWriter);
                    xmlWriter.Flush();
                    memoryStream.Flush();
                    return Encoding.UTF8.GetString(memoryStream.ToArray());
                }
            }
        }