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
}
}