Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace XmlDocumentMerger
- {
- using System;
- using System.Linq;
- using System.Text;
- using System.Xml;
- /*
- * Use this class for quickly merging two XML web.config files into one file.
- * 2015-06-30, Uwe Keim, http://www.zeta-test.com
- */
- public static class XmlDocumentMergeController
- {
- public static string MergeDocuments(
- string xmlToMergeFrom,
- string xmlToMergeInto)
- {
- if (string.IsNullOrEmpty(xmlToMergeFrom)) return xmlToMergeInto;
- else if (string.IsNullOrEmpty(xmlToMergeInto)) return xmlToMergeFrom;
- else if (string.IsNullOrEmpty(xmlToMergeFrom) &&
- string.IsNullOrEmpty(xmlToMergeInto)) return xmlToMergeInto;
- // --
- var sourceDoc = new XmlDocument();
- var destDoc = new XmlDocument();
- sourceDoc.LoadXml(xmlToMergeFrom);
- destDoc.LoadXml(xmlToMergeInto);
- // --
- foreach (
- var sourceNode in sourceDoc.ChildNodes.Cast<XmlNode>().Where(n => n.NodeType == XmlNodeType.Element))
- {
- doProcessNode(sourceNode, destDoc);
- }
- // --
- return destDoc.OuterXml;
- }
- private static void doProcessNode(XmlNode sourceNode, XmlNode destParentNode)
- {
- var destNode = findNode(sourceNode, destParentNode.OwnerDocumentIntelligent());
- if (destNode == null)
- {
- // Gibt es noch nicht, einfach rüber kopieren.
- copyNode(sourceNode, destParentNode);
- }
- else
- {
- // Gibt es schon, Inhalt verarbeiten.
- foreach (
- var childNode in sourceNode.ChildNodes.Cast<XmlNode>().Where(n => n.NodeType == XmlNodeType.Element)
- )
- {
- doProcessNode(childNode, destNode);
- }
- }
- }
- private static void copyNode(XmlNode sourceNode, XmlNode destParentNode)
- {
- // ReSharper disable once PossibleNullReferenceException
- var newNode = destParentNode.OwnerDocumentIntelligent().ImportNode(sourceNode, true);
- destParentNode.AppendChild(newNode);
- }
- private static XmlNode findNode(XmlNode sourceNode, XmlNode destDoc)
- {
- var xPath = findXPath(sourceNode);
- var destNode = destDoc.SelectSingleNode(xPath);
- return destNode;
- }
- // http://stackoverflow.com/a/241291/107625
- private static string findXPath(XmlNode node)
- {
- var builder = new StringBuilder();
- while (node != null)
- {
- switch (node.NodeType)
- {
- case XmlNodeType.Attribute:
- builder.Insert(0, string.Format(@"/@{0}", node.Name));
- node = ((XmlAttribute) node).OwnerElement;
- break;
- case XmlNodeType.Element:
- var index = findElementIndex((XmlElement) node);
- builder.Insert(0, string.Format(@"/{0}[{1}]", node.Name, index));
- node = node.ParentNode;
- break;
- case XmlNodeType.Document:
- return builder.ToString();
- default:
- throw new ArgumentException("Only elements and attributes are supported");
- }
- }
- throw new ArgumentException("Node was not in a document");
- }
- private static int findElementIndex(XmlNode element)
- {
- var parentNode = element.ParentNode;
- if (parentNode is XmlDocument)
- {
- return 1;
- }
- var parent = (XmlElement) parentNode;
- var index = 1;
- if (parent != null)
- {
- foreach (XmlNode candidate in parent.ChildNodes)
- {
- if (candidate is XmlElement && candidate.Name == element.Name)
- {
- if (candidate == element)
- {
- return index;
- }
- index++;
- }
- }
- }
- throw new ArgumentException("Couldn't find element within parent");
- }
- }
- internal static class XmlExtensions
- {
- public static XmlDocument OwnerDocumentIntelligent(this XmlNode node)
- {
- if (node == null) return null;
- else
- {
- var document = node as XmlDocument;
- return document ?? node.OwnerDocument;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement