批量合并xml文件

/// 
/// 对由爬虫爬取的职位类xml文件进行批量格式化(去除非打印字符,提取有用节点)并拼接成一个xml文件,方便数据库或Excel导入。
/// 
class XMLCombine
{
    private string SavePath { get; set; }//拼接后的xml文件保存或加载路径(包括文件名)
    private XDocument XML { get; set; }//将指定路径的xml加载进XDocument类。
    public XMLCombine(string savePath)
    {
        this.SavePath = savePath;
        if (!File.Exists(savePath))
        {
            XDocument xWrite = new XDocument();
            XElement xJobs = new XElement("Jobs");
            xWrite.Add(xJobs);
            xWrite.Save(savePath);//创建xml文件
        }
        this.XML = XDocument.Load(savePath);
    }
    /// 
    /// 对由招聘网站爬取的分页的职位列表-xml文件进行字段提取,合并。
    /// 
    /// 批量导入的xml文件所在的目录
    /// 需要从xml文件中提取的字段(节点)
    /// 准备导入的xml文件的编码格式
    /// 文本形式保存的新增/修改的职位数和对新xml文件导入时的查重
    public string AddNewPost(string path, string posts, Encoding rTF)
    {
        int countAdd = 0;//新增/更新的职位数
        int countRepeat1 = 0;//新导入的xml文件中的职位重复数。
        int countRepeat2 = 0;//新导入的职位信息与原已拼接的xml文件的职位重复数
        Dictionary selectInfo = new Dictionary();//key为职位主页的网址(作为查重依据),value为以单个职位信息作为的节点
        string[] thisPosts = posts.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
        IEnumerable filesEnum = Directory.EnumerateFiles(path, "*.xml");//遍历指定文件夹下的xml文件
        IEnumerator paths = filesEnum.GetEnumerator();
        while (paths.MoveNext())
        {
            string str = File.ReadAllText(paths.Current, rTF);
            StringBuilder sb = new StringBuilder();
            foreach (char cc in str)//将xml对象中包含的低序位非打印 ASCII 字符去除,以免XDocment读取异常
            {
                int ss = (int)cc;
                if (((ss >= 0) && (ss <= 8)) || ((ss >= 11) && (ss <= 12)) || ((ss >= 14) && (ss <= 32)))
                { sb.AppendFormat(" ", ss); }
                else { sb.Append(cc); }
            }
            str = sb.ToString();
            XDocument readXdoc = XDocument.Parse(str);//将格式化后的字符串创建为XDocment对象
            //DescendantsAndSelf(XName):从XElements集合的的所有元素及其子代元素中查找指定XName的元素,返回第一个。
            XElement jobInfos = readXdoc.Elements().DescendantsAndSelf("职位信息").First();
            foreach (XElement jobInfo in jobInfos.Elements())
            {
                XElement newJob = new XElement("Person");
                for (int i = 0; i < thisPosts.Length; i++)
                {
                    string name = thisPosts[i];
                    XElement xel = jobInfo.Element(name);//检索子元素下指定名称的第一个元素(节点)
                    //去除多余的空字符和换行符
                    string temp = string.Join(" ", xel.Value.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
                    string value = string.Join("\n", temp.Split(new string[] { "\n ", " \n", "\n" }, StringSplitOptions.RemoveEmptyEntries));
                    newJob.SetElementValue(name, value);
                }
                string webSite = newJob.Element("网址").Value;
                if (!selectInfo.ContainsKey(webSite))
                {
                    selectInfo.Add(webSite, newJob);//将格式化并查重后的每个职位信息存入字典,以职位主页网址为索引
                    countAdd++;
                }
                else countRepeat1++;
            }
        }
        XElement oldRoot = this.XML.Root;
        foreach (XElement item in oldRoot.Elements())
        {
            string selectWebSite = item.Element("网址").Value;
            //变量原已拼接的xml文件中的职位,判断每个职位的网址是否与字典中职位的网站相同,如果是,则去除字典中的重复职位,将剩余不重复的加入xml文件中
            if (selectWebSite!=null&&selectInfo.ContainsKey(selectWebSite))
            {
                selectInfo.Remove(selectWebSite);//从字典中移除指定Key的元素
                countRepeat2++;
            }
        }
        oldRoot.Add(selectInfo.Values);
        this.XML.Save(this.SavePath);
        countAdd = countAdd - countRepeat2;
        return "新增职位数:" + countAdd + ",准备导入的批量xml之中的职位重复数:" + countRepeat1 + ",准备导入的批量xml与原保存的xml数据中的重复职位数:" + countRepeat2;
    }
    /// 
    /// 对由爬虫从招聘网站爬取的每个职位主页信息进行格式化(去除非打印字符,提取有用节点),拼接进包含职位列表的xml文件,方便数据库或Excel导入。
    /// 
    /// 批量导入的xml文件所在的目录
    /// 需要从xml文件中提取的字段(节点:职位信息)
    /// 准备导入的xml文件的编码格式
    /// 文本形式保存的新增/修改的职位数和对新xml文件导入时的查重
    public string AddNewRepresent(string path, string represents, Encoding rTF)
    {
        int countAdd = 0;
        int countRepeat1 = 0;
        int countRepeat2 = 0;
        Dictionary selectInfo = new Dictionary();
        string[] thisRepresents = represents.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); ;
        IEnumerable filesEnum = Directory.EnumerateFiles(path, "*.xml");
        IEnumerator paths = filesEnum.GetEnumerator();
        while (paths.MoveNext())
        {
            string str = File.ReadAllText(paths.Current, rTF);
            StringBuilder info = new StringBuilder();
            foreach (char cc in str)
            {
                int ss = (int)cc;
                if (((ss >= 0) && (ss <= 8)) || ((ss >= 11) && (ss <= 12)) || ((ss >= 14) && (ss <= 32)))
                    info.AppendFormat(" ", ss);
                else info.Append(cc);
            }
            str = info.ToString();
            XDocument xml = XDocument.Parse(str);
            XElement xPerson = new XElement("Person");
            for (int i = 0; i < thisRepresents.Length; i++)
            {
                string name = thisRepresents[i];
                XElement xel = xml.Root.DescendantsAndSelf(name).First();
                string temp = string.Join(" ", xel.Value.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
                string value = string.Join("\n", temp.Split(new string[] { "\n ", " \n", "\n" }, StringSplitOptions.RemoveEmptyEntries));
                //招聘部门这个字段中,默认包含了“企业名+部门”,将企业名去除。
                if (name == "招聘部门")
                {
                    value = value.Replace(xml.Root.DescendantsAndSelf("企业名").First().Value.Trim(), "");
                }
                xPerson.SetElementValue(name, value);//将获取的节点格式化后(去除空字符)写入新的XDocment对象下
            }
            //职位主页的网址在fullpath这个字段中。
            string webSite = xml.Root.DescendantsAndSelf("fullpath").First().Value.Trim();
            if (!selectInfo.ContainsKey(webSite))
            {
                selectInfo.Add(webSite, xPerson);
            }
            else countRepeat1++;
        }
        XElement oldRoot = this.XML.Root;
        foreach (XElement item in oldRoot.Elements())
        {
            string selectWebSite = item.Element("网址").Value;
            XElement addInfo = selectInfo[selectWebSite];
            //遍历已拼接的xml文件中的职位,如果职位的网址与字典中的职位主页的网址相同,并且判断字典中该职位信息未加入到该xml文件中,则向xml文件添加进字典中该职位的信息
            if (selectWebSite!=null&&
                item.LastNode.ToString() !=addInfo.LastNode.ToString()&&
                selectInfo.ContainsKey(selectWebSite))
            {
                item.Add(addInfo.Elements());
                ++countAdd;
            }
            else countRepeat2++;
        }
        this.XML.Save(this.SavePath);
        return  "补全职位数:" + countAdd + ",准备导入的批量xml之中的职位重复数:" + countRepeat1 + ",准备导入的批量xml与原保存的xml数据中的重复职位数:" + countRepeat2;
    }
}

你可能感兴趣的:(批量合并xml文件)