C#操作Xml树的扩展类

本文提供一个操作Xml树的扩展类,与将xml字符串直接映射成实体对象的使用方法,供大家参考,学习。

下面附上源码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Xml.Linq;
using WoT.Infrastructure.Helper.Web;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml.Serialization;

namespace WoT.Infrastructure.Helper.Xml
{
    /// <summary>
    /// 操作Xml树的扩展类
    /// Author: Jacky
    /// </summary>
    public static class XmlExpand
    {

        /// <summary>
        /// 锁对象
        /// </summary>
        private static object objLock = new object();


        /// <summary>
        /// 获取路径的值。如果不存在则返回defaultValue 路径用/隔开
        /// 支持获取同名同级节点中的某个,格式: elementName[index] 从0开始
        /// </summary>
        public static string GetValue(this XElement element, string xPath, string defaultValue = null)
        {
            element = element.GetElement(xPath);
            return element == null ? defaultValue : element.Value;
        }

        /// <summary>
        /// 获取属性值 如果不存在则返回defaultValue
        /// </summary>
        public static string GetAttributeValue(this XElement element, string name)
        {
            if (element.Attribute(name) == null) return null;
            string value = element.Attribute(name).Value;
            return value;
        }

        /// <summary>
        /// 获取路径的节点。如果不存在则返回defaultValue 路径用/隔开
        /// 支持获取同名同级节点中的某个,格式: elementName[index] 从0开始
        /// </summary>
        public static XElement GetElement(this XElement element, string xPath)
        {
            Regex regex = new Regex(@"(?<Name>.*)\[(?<Index>\d+)\]", RegexOptions.IgnoreCase);
            try
            {
                foreach (string tag in xPath.Split('/'))
                {
                    if (regex.IsMatch(tag))
                    {
                        string tagName = regex.Match(tag).Groups["Name"].Value;
                        int index = int.Parse(regex.Match(tag).Groups["Index"].Value);
                        element = element.Elements(tagName).ToArray()[index];
                    }
                    else
                    {
                        element = element.Element(tag);
                    }
                    if (element == null) return null;

                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message + "\n" + xPath);
            }
            return element;

        }

        /// <summary>
        /// 两个XML合并 把obj拥有而root没有的节点和属性复制给root
        /// </summary>
        /// <param name="root">原始的对象</param>
        /// <param name="obj"></param>
        public static XElement Merger(this XElement root, XElement obj)
        {
            XmlMerger(root, obj);
            return root;
        }

        /// <summary>
        /// 递归对比两个节点,把obj拥有而root没有的节点复制到root中
        /// </summary>
        /// <param name="root"></param>
        /// <param name="obj"></param>
        private static void XmlMerger(XElement root, XElement obj)
        {
            foreach (XElement element in obj.Elements())
            {
                var childElements = root.Elements(element.Name);

                if (childElements.Count() == 0)
                {
                    root.Add(element);
                }
                else if (childElements.Count() == 1)    // 有且只有一个同名节点才启动复制递归规则
                {
                    XElement childElement = childElements.First();
                    foreach (XAttribute attribute in element.Attributes())
                    {
                        if (childElement.Attributes(attribute.Name).Count() == 0)
                            childElement.SetAttributeValue(attribute.Name, attribute.Value);
                    }
                    XmlMerger(childElement, element);
                }
            }
        }

        /// <summary>
        /// 遍历所有的子元素中包含名称的节点
        /// </summary>
        /// <param name="tagName"></param>
        /// <returns></returns>
        public static List<XElement> GetElements(this XElement root, params string[] tagName)
        {
            List<XElement> list = new List<XElement>();
            GetElements(root, list, tagName);
            return list;
        }

        private static void GetElements(XElement root, List<XElement> list, params string[] tagName)
        {
            foreach (XElement el in root.Elements())
            {
                if (tagName.Contains(el.Name.ToString()))
                {
                    list.Add(el);
                }
                GetElements(el, list, tagName);
            }
        }

        /// <summary>
        /// XML转实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strXML"></param>
        /// <returns></returns>
        public static T DESerializer<T>(string strXML) where T : class
        {
            try
            {
                using (StringReader sr = new StringReader(strXML))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(sr) as T;
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// 从XML字符串中反序列化对象
        /// </summary>
        /// <typeparam name="T">结果对象类型</typeparam>
        /// <param name="xml">包含对象的XML字符串</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>反序列化得到的对象</returns>
        public static T XmlDeserialize<T>(string xml, Encoding encoding)
        {
            if (string.IsNullOrEmpty(xml))
                throw new ArgumentNullException("xml is null");
            if (encoding == null)
                throw new ArgumentNullException("encoding");

            XmlSerializer mySerializer = new XmlSerializer(typeof(T));
            using (MemoryStream ms = new MemoryStream(encoding.GetBytes(xml)))
            {
                using (StreamReader sr = new StreamReader(ms, encoding))
                {
                    return (T)mySerializer.Deserialize(sr);
                }
            }
        }

    }
}
操作Xml树的扩展类

 

将xml字符串直接映射成实体对象

一段代码搞定

 

 

PS:扫描下方二维码或点击链接,加入QQ群

一群用代码改变世界的

posted @ 2018-07-03 14:42  Jack_000  阅读(557)  评论(0编辑  收藏  举报