/// <summary> /// Set the value of, or remove, target nodes. /// </summary> /// <param name="source">The source xml to transform.</param> /// <param name="destination">The destination to write too.</param> /// <param name="xpath">The xpath of the nodes to set.</param> /// <param name="value">The value to set too. Leave blank to remove the selected nodes.</param> /// <param name="settings">Additional settings to tweak Xml Poke behavior.</param> private static void XmlPoke(Stream source, Stream destination, string xpath, string value, XmlPokeSettings settings) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (destination == null) { throw new ArgumentNullException(nameof(destination)); } if (string.IsNullOrWhiteSpace(xpath)) { throw new ArgumentNullException(nameof(xpath)); } if (settings == null) { throw new ArgumentNullException(nameof(settings)); } using (var xmlReader = XmlReader.Create(source, GetXmlReaderSettings(settings))) { // Load the document from the reader var document = new XmlDocument(); document.PreserveWhitespace = settings.PreserveWhitespace; document.Load(xmlReader); // Add namespaces var namespaceManager = new XmlNamespaceManager(document.NameTable); foreach (var xmlNamespace in settings.Namespaces) { namespaceManager.AddNamespace(xmlNamespace.Key /* Prefix */, xmlNamespace.Value /* URI */); } // Select the desired nodes var nodes = document.SelectNodes(xpath, namespaceManager); if (nodes == null || nodes.Count == 0) { const string format = "Failed to find nodes matching the XPath '{0}'"; var message = string.Format(CultureInfo.InvariantCulture, format, xpath); throw new CakeException(message); } // Adjust the nodes / values if (value == null) { // Remove the nodes foreach (XmlNode node in nodes) { // ReSharper disable once PossibleNullReferenceException // Pretty sure we should never be working with orphaned nodes. node.ParentNode.RemoveChild(node); } } else { // Set the value foreach (XmlNode node in nodes) { node.InnerXml = value; } } // Get the writer settings var writerSettings = GetXmlWriterSettings(settings); // Adjust the writer settings according to the declaration var hasDeclaration = document.FirstChild.NodeType == XmlNodeType.XmlDeclaration; if (!hasDeclaration) { writerSettings.OmitXmlDeclaration = true; } // Write the document using (var xmlWriter = XmlWriter.Create(destination, writerSettings)) { document.Save(xmlWriter); } } }
public static string XmlPokeString(this ICakeContext context, string sourceXml, string xpath, string value, XmlPokeSettings settings) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrWhiteSpace(sourceXml)) { throw new ArgumentNullException(nameof(sourceXml)); } using (var resultStream = new MemoryStream()) { using (var sourceStream = new MemoryStream(settings.Encoding.GetBytes(sourceXml))) { XmlPoke(sourceStream, resultStream, xpath, value, settings); } resultStream.Position = 0; return(settings.Encoding.GetString(resultStream.ToArray())); } }
public static void XmlPoke(this ICakeContext context, FilePath filePath, string xpath, string value, XmlPokeSettings settings) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (filePath == null) { throw new ArgumentNullException(nameof(filePath)); } if (settings == null) { throw new ArgumentNullException(nameof(settings)); } var file = context.FileSystem.GetFile(filePath); if (!file.Exists) { throw new FileNotFoundException("Source File not found.", file.Path.FullPath); } using (var resultStream = new MemoryStream()) { using (var fileStream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None)) { XmlPoke(fileStream, resultStream, xpath, value, settings); } using (var fileStream = file.Open(FileMode.Create, FileAccess.Write, FileShare.None)) { resultStream.Position = 0; resultStream.CopyTo(fileStream); } } }
/// <summary> /// Set the value of, or remove, target nodes. /// </summary> /// <param name="source">The source xml to transform.</param> /// <param name="destination">The destination to write too.</param> /// <param name="xpath">The xpath of the nodes to set.</param> /// <param name="value">The value to set too. Leave blank to remove the selected nodes.</param> /// <param name="settings">Additional settings to tweak Xml Poke behavior.</param> private static void XmlPoke(XmlReader source, XmlWriter destination, string xpath, string value, XmlPokeSettings settings) { if (source == null) { throw new ArgumentNullException("source"); } if (destination == null) { throw new ArgumentNullException("destination"); } if (string.IsNullOrWhiteSpace(xpath)) { throw new ArgumentNullException("xpath"); } if (settings == null) { throw new ArgumentNullException("settings"); } var document = new XmlDocument(); document.PreserveWhitespace = settings.PreserveWhitespace; document.Load(source); var namespaceManager = new XmlNamespaceManager(document.NameTable); foreach (var xmlNamespace in settings.Namespaces) { namespaceManager.AddNamespace(xmlNamespace.Key /* Prefix */, xmlNamespace.Value /* URI */); } var nodes = document.SelectNodes(xpath, namespaceManager); if (nodes == null || nodes.Count == 0) { const string format = "Failed to find nodes matching the XPath '{0}'"; var message = string.Format(CultureInfo.InvariantCulture, format, xpath); throw new CakeException(message); } if (value == null) { foreach (XmlNode node in nodes) { // ReSharper disable once PossibleNullReferenceException // Pretty sure we should never be working with orphaned nodes. node.ParentNode.RemoveChild(node); } } else { foreach (XmlNode node in nodes) { node.InnerXml = value; } } document.Save(destination); }
public static string XmlPokeString(this ICakeContext context, string sourceXml, string xpath, string value, XmlPokeSettings settings) { if (context == null) { throw new ArgumentNullException("context"); } if (string.IsNullOrWhiteSpace(sourceXml)) { throw new ArgumentNullException("sourceXml"); } using (var resultStream = new MemoryStream()) using (var fileReader = new StringReader(sourceXml)) using (var xmlReader = XmlReader.Create(fileReader, GetXmlReaderSettings(settings))) using (var xmlWriter = XmlWriter.Create(resultStream)) { XmlPoke(xmlReader, xmlWriter, xpath, value, settings); resultStream.Position = 0; return(settings.Encoding.GetString(resultStream.ToArray())); } }
public static string XmlPoke(this ICakeContext context, string sourceXml, string xpath, string value, XmlPokeSettings settings) { return(context.XmlPokeString(sourceXml, xpath, value, settings)); }