using System.IO; using System.Net; using System.Xml; using System.Xml.Serialization; using System; using System.Text; using System.Collections.Generic; using System.Xml.Schema; using System.Dynamic; using System.Xml.Linq; using System.Linq; namespace EasyDevCore.Common { /// /// Xml Utils /// public sealed class XmlHelper { #region NodeNavigator Class /// /// Class required to navigate through children nodes /// private class NodeNavigator { // Recursively loop over a node subtree internal static void LoopThroughChildren(XmlTextWriter writer, XmlNode rootNode) { // Write the start tag if (rootNode.NodeType == XmlNodeType.Element) { writer.WriteStartElement(rootNode.Name); // Write any attributes foreach (XmlAttribute attr in rootNode.Attributes) { writer.WriteAttributeString(attr.Name, attr.Value); } // Write any child nodes foreach (XmlNode node in rootNode.ChildNodes) { LoopThroughChildren(writer, node); } // Write the end tag writer.WriteEndElement(); } else { // Write any text if (rootNode.NodeType == XmlNodeType.Text) { writer.WriteString(rootNode.Value); } } } } #endregion #region Public Methods /// /// Converts XML document to string. /// /// The XML doc. /// public static string DocToString(XmlDocument xmlDoc) { StringBuilder sb = new(); StringWriter sw = new(sb); xmlDoc.Save(sw); return sw.ToString(); } /// /// Gets the XML doc from URL /// /// The stream. /// public static XmlDocument CreateDocument(Stream stream) { XmlDocument xmlDoc = new(); XmlReaderSettings settings = new(); //Bỏ qua ghi chú và các chỉ dẫn xử lý settings.IgnoreComments = true; settings.IgnoreProcessingInstructions = true; settings.IgnoreWhitespace = true; XmlReader reader = null; try { reader = XmlReader.Create(stream, settings); xmlDoc.Load(reader); } finally { if (reader != null) { reader.Close(); } } return xmlDoc; } /// /// Creates the XML document. /// /// Name of the root. /// public static XmlDocument CreateDocument(string rootName) { XmlDocument doc = new(); XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", ""); doc.InsertBefore(decl, doc.DocumentElement); if (!string.IsNullOrEmpty(rootName)) { XmlNode newNode = doc.CreateElement(rootName); doc.AppendChild(newNode); } return doc; } /// /// Creates the XML document. /// /// public static XmlDocument CreateDocument() { return CreateDocument(string.Empty); } /// /// Adds the child node. /// /// The parent node. /// The node names. /// public static XmlNode[] AddChildNodes(XmlNode parentNode, params string[] nodeNames) { XmlDocument doc = parentNode.OwnerDocument; if (doc == null) //Root ? { doc = (XmlDocument)parentNode; } XmlNode[] list = new XmlNode[nodeNames.Length]; for (int i = 0; i < nodeNames.Length; i++) { var newNode = doc.CreateElement(nodeNames[i]); list[i] = parentNode.AppendChild(newNode); } return list; } /// /// Adds the child node with attributes. /// /// The parent node. /// Name of the node. /// The value. /// Name of the attr. /// The attr value. /// public static XmlNode AddSingleChildNode(XmlNode parentNode, string nodeName, object value, string attrName, string attrValue) { XmlDocument doc = parentNode.OwnerDocument; if (doc == null) //Root ? { doc = (XmlDocument)parentNode; } var newNode = doc.CreateElement(nodeName); if (attrName != null) { AddNodeAttribute(newNode, attrName, attrValue); } parentNode.AppendChild(newNode); newNode.InnerText = ConvertHelper.StringFrom(value); return newNode; } /// /// Adds the single child node with value /// /// The parent node. /// Name of the node. /// The value. /// public static XmlNode AddSingleChildNode(XmlNode parentNode, string nodeName, object value) { return AddSingleChildNode(parentNode, nodeName, value, null, null); } /// /// Selects the node. /// /// The parent node. /// Name of the node. /// public static XmlNode SelectSingleNode(XmlNode parentNode, string nodeName) { return parentNode.SelectSingleNode(nodeName); } /// /// Selects the nodes. /// /// The parent node. /// Name of the node. /// public static XmlNodeList SelectNodes(XmlNode parentNode, string nodeName) { return parentNode.SelectNodes(nodeName); } /// /// Selects the node. /// /// The parent node. /// Name of the attr. /// The attr value. /// public static XmlNode SelectSingleNode(XmlNode parentNode, string attrName, object attrValue) { XmlNode childNode = null; if (parentNode.HasChildNodes) { string nodeName = parentNode.ChildNodes[0].Name; string path = nodeName + "[@" + attrName + "='" + attrValue.ToString() + "']"; childNode = parentNode.SelectSingleNode(path); } return childNode; } /// /// Sets the node value. /// /// The node. /// Name of the node. /// The value. /// public static bool SetNodeValue(XmlNode node, string nodeName, object value) { bool success = false; try { node[nodeName].InnerText = ConvertHelper.StringFrom(value); success = true; } catch(Exception) { } return success; } /// /// Gets the node value string. /// /// The node. /// Name of the node. /// The default value. /// public static string GetNodeValue(XmlNode node, string nodeName, string defaultValue) { string value = defaultValue; if(node[nodeName] != null) { value = node[nodeName].InnerText; } return value; } /// /// Gets the node value string. /// /// The node. /// Name of the node. /// public static string GetNodeValue(XmlNode node, string nodeName) { return GetNodeValue(node, nodeName, string.Empty); } /// /// Gets the node value. /// /// The type of value. /// The parent node. /// Name of the node. /// The default value. /// public static T GetNodeValue(XmlNode parentNode, string nodeName, T defaultValue) { #pragma warning disable CS8602 // Dereference of a possibly null reference. return ConvertHelper.StringTo(parentNode[nodeName].InnerText, defaultValue); #pragma warning restore CS8602 // Dereference of a possibly null reference. } /// /// Gets the node value. /// /// The type of value. /// The parent node. /// Name of the node. /// public static T GetNodeValue(XmlNode parentNode, string nodeName) { return GetNodeValue(parentNode, nodeName, default); } /// /// Creates the node attribute. /// /// The node. /// Name of the attr. /// The value. /// public static XmlAttribute AddNodeAttribute(XmlNode node, string attrName, object value) { XmlAttribute attr = null; try { attr = node.OwnerDocument.CreateAttribute(attrName); attr.Value = value.ToString(); node.Attributes.SetNamedItem(attr); } catch(Exception) { } return attr; } /// /// Sets the node attribute. /// /// The node. /// Name of the attr. /// The value. /// public static bool SetNodeAttribute(XmlNode node, string attrName, object value) { bool success = false; try { node.Attributes[attrName].Value = ConvertHelper.StringFrom(value); success = true; } catch(Exception) { } return success; } /// /// Copies the node attribute. /// /// From node. /// To node. /// Name of the attr. /// public static bool CopyNodeAttribute(XmlNode fromNode, XmlNode toNode, string attrName) { bool success = true; try { XmlAttribute fromAttr = fromNode.Attributes[attrName]; XmlAttribute toAttr = toNode.Attributes[attrName]; if (fromAttr != null) { if (toAttr == null) { toAttr = AddNodeAttribute(toNode, attrName, fromAttr.Value); } else { SetNodeAttribute(toNode, attrName, fromAttr.Value); } } } catch(Exception) { success = false; } return success; } /// /// Gets the node attribute string. /// /// The node. /// Name of the attr. /// The default value. /// public static string GetNodeAttribute(XmlNode node, string attrName, string defaultValue) { string value = defaultValue; if (node != null && node.Attributes[attrName] != null) { try { value = node.Attributes[attrName].InnerText; } catch (Exception) { } } return value; } /// /// Gets the node attribute string. /// /// The node. /// Name of the attr. /// public static string GetNodeAttribute(XmlNode node, string attrName) { return GetNodeAttribute(node, attrName, null); } /// /// Gets the node attribute. /// /// The type of attribute. /// The node. /// Name of the attr. /// The default value. /// public static T GetNodeAttribute(XmlNode node, string attrName, T defaultValue) { return ConvertHelper.StringTo(node.Attributes[attrName].InnerText, defaultValue); } /// /// Gets the node attribute. /// /// The type of attribute. /// The node. /// Name of the attr. /// public static T GetNodeAttribute(XmlNode node, string attrName) { return GetNodeAttribute(node, attrName, default); } /// /// The XML node to string. /// /// The node. /// public static string NodeToString(XmlNode node) { StringWriter sw = new(new StringBuilder("")); XmlTextWriter writer = new(sw); writer.Formatting = Formatting.Indented; if (node == null) { writer.WriteStartElement(string.Empty); } else { writer.WriteStartElement(node.Name); // Write any attributes foreach (XmlAttribute attr in node.Attributes) { writer.WriteAttributeString(attr.Name, attr.Value); } // Write child nodes XmlNodeList nodes = node.SelectNodes("child::*"); if (nodes != null) { foreach (XmlNode n in nodes) { NodeNavigator.LoopThroughChildren(writer, n); } } } writer.WriteEndElement(); writer.Close(); return sw.ToString(); } /// /// The XmlNodeList to string. /// /// The node list. /// public static string NodeListToString(XmlNodeList nodeList) { if (nodeList != null) { StringBuilder sb = new(); foreach (XmlNode node in nodeList) { if (sb.Length == 0) sb.Append(NodeToString(node)); else sb.Append("\r\n" + NodeToString(node)); } return sb.ToString(); } return string.Empty; } /// /// Serializes the specified value. /// /// The value. /// public static string Serialize(object value) { XmlSerializer serialize = new(value.GetType()); XmlDocument doc = new(); using (StringWriter writer = new()) { serialize.Serialize(writer, value); doc.LoadXml(writer.GetStringBuilder().ToString()); } return doc.OuterXml; } /// /// Deserializes the specified value. /// /// /// The value. /// public static T Deserialize(string value) { object result = Deserialize(value, typeof(T)); if (result == null) return default; return (T)result; } /// /// Deserializes the specified value. /// /// The value. /// The type. /// public static object Deserialize(string value, Type type) { XmlSerializer serializer = new(type); StringReader reader = new(value); try { return serializer.Deserialize(reader); } catch { } return null; } /// /// Replaces invalid XML characters in a string with their valid XML equivalent. /// /// The value within which to escape invalid characters. public static string EscapeXML(string value) { return System.Security.SecurityElement.Escape(value); } /// /// Unescapes the XML. /// /// The value. /// public static string UnescapeXML(string value) { if (string.IsNullOrEmpty(value)) return value; if(value.IndexOf("'") > -1) value = value.Replace("'", "'"); if (value.IndexOf(""") > -1) value = value.Replace(""", "\""); if (value.IndexOf(">") > -1) value = value.Replace(">", ">"); if (value.IndexOf("<") > -1) value = value.Replace("<", "<"); if (value.IndexOf("&") > -1) value = value.Replace("&", "&"); return value; } #endregion } }