Example #1
0
        public void GetDigestMethod()
        {
#if NET452
            var expected = "http://www.w3.org/2000/09/xmldsig#sha1";
#endif
#if NET471
            var expected = "http://www.w3.org/2001/04/xmlenc#sha256";
#endif
            Assert.AreEqual(expected, XmlReference.GetDigestMethod());
        }
Example #2
0
        /// <summary>
        /// Load the selected XML file and its associated custom file.
        /// </summary>
        /// <param name="strFileName">Name of the XML file to load.</param>
        public XmlDocument Load(string strFileName)
        {
            string strPath = Path.Combine(Environment.CurrentDirectory, "data", strFileName);
            DateTime datDate = File.GetLastWriteTime(strPath);

            // Look to see if this XmlDocument is already loaded.
            bool blnFound = false;
            XmlReference objReference = new XmlReference();
            foreach (XmlReference objCurrentReference in _lstXmlDocuments)
            {
                if (objCurrentReference.FileName == strFileName)
                {
                    objReference = objCurrentReference;
                    blnFound = true;
                    break;
                }
            }

            bool blnLoadFile = false;
            if (!blnFound)
            {
                // The file was not found in the reference list, so it must be loaded.
                blnLoadFile = true;
                _lstXmlDocuments.Add(objReference);
            }
            else
            {
                // The file was found in the List, so check the last write time.
                if (datDate != objReference.FileDate)
                {
                    // The last write time does not match, so it must be reloaded.
                    blnLoadFile = true;
                }
            }

            // Create a new document that everything will be merged into.
            XmlDocument objDoc = new XmlDocument();
            // write the root chummer node.
            XmlNode objCont = objDoc.CreateElement("chummer");
            objDoc.AppendChild(objCont);

            XmlDocument objXmlFile = new XmlDocument();
            XmlNodeList objList;

            if (blnLoadFile)
            {
                // Load the base file and retrieve all of the child nodes.
                objXmlFile.Load(strPath);
                objList = objXmlFile.SelectNodes("/chummer/*");
                foreach (XmlNode objNode in objList)
                {
                    // Append the entire child node to the new document.
                    XmlNode objImported = objDoc.ImportNode(objNode, true);
                    objDoc.DocumentElement.AppendChild(objImported);
                }

                // Load any override data files the user might have. Do not attempt this if we're loading the Improvements file.
                if (strFileName != "improvements.xml")
                {
                    string strFilePath = Path.Combine(Environment.CurrentDirectory, "data");
                    foreach (string strFile in Directory.GetFiles(strFilePath, "override*_" + strFileName))
                    {
                        objXmlFile.Load(strFile);
                        objList = objXmlFile.SelectNodes("/chummer/*");
                        foreach (XmlNode objNode in objList)
                        {
                            foreach (XmlNode objType in objNode.ChildNodes)
                            {
                                if (objType["id"] != null)
                                {
                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objNode.Name + "/" + objType.Name + "[id = \"" + objType["id"].InnerText.Replace("&amp;", "&") + "\"]");
                                    if (objItem != null)
                                        objItem.InnerXml = objType.InnerXml;
                                }
                                else if (objType["name"] != null)
                                {
                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objNode.Name + "/" + objType.Name + "[name = \"" + objType["name"].InnerText.Replace("&amp;", "&") + "\"]");
                                    if (objItem != null)
                                        objItem.InnerXml = objType.InnerXml;
                                }
                            }
                        }
                    }
                }

                // Load the translation file for the current base data file if the selected language is not en-us.
                if (GlobalOptions.Instance.Language != "en-us")
                {
                    // Everything is stored in the selected language file to make translations easier, keep all of the language-specific information together, and not require users to download 27 individual files.
                    // The structure is similar to the base data file, but the root node is instead a child /chummer node with a file attribute to indicate the XML file it translates.
                    if (LanguageManager.Instance.DataDoc != null)
                    {
                        foreach (XmlNode objNode in LanguageManager.Instance.DataDoc.SelectNodes("/chummer/chummer[@file = \"" + strFileName + "\"]"))
                        {
                            foreach (XmlNode objType in objNode.ChildNodes)
                            {
                                foreach (XmlNode objChild in objType.ChildNodes)
                                {
                                    // If this is a translatable item, find the proper node and add/update this information.
                                    if (objChild["translate"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                            objItem.InnerXml += "<translate>" + objChild["translate"].InnerXml + "</translate>";
                                    }
                                    if (objChild["page"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                            objItem.InnerXml += "<altpage>" + objChild["page"].InnerXml + "</altpage>";
                                    }
                                    if (objChild["code"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                            objItem.InnerXml += "<altcode>" + objChild["code"].InnerXml + "</altcode>";
                                    }
                                    if (objChild["advantage"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                            objItem.InnerXml += "<altadvantage>" + objChild["advantage"].InnerXml + "</altadvantage>";
                                    }
                                    if (objChild["disadvantage"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                            objItem.InnerXml += "<altdisadvantage>" + objChild["disadvantage"].InnerXml + "</altdisadvantage>";
                                    }
                                    if (objChild.Attributes != null)
                                    {
                                        // Handle Category name translations.
                                        if (objChild.Attributes["translate"] != null)
                                        {
                                            XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[. = \"" + objChild.InnerXml.Replace("&amp;", "&") + "\"]");
                                            if (objItem != null)
                                            {
                                                XmlElement objElement = (XmlElement)objItem;
                                                objElement.SetAttribute("translate", objChild.Attributes["translate"].InnerXml);
                                            }
                                        }
                                    }

                                    // Check for Skill Specialization information.
                                    if (strFileName == "skills.xml")
                                    {
                                        if (objChild["specs"] != null)
                                        {
                                            foreach (XmlNode objSpec in objChild.SelectNodes("specs/spec"))
                                            {
                                                if (objSpec.Attributes["translate"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/skill[name = \"" + objChild["name"].InnerXml + "\"]/specs/spec[. = \"" + objSpec.InnerXml + "\"]");
                                                    if (objItem != null)
                                                    {
                                                        XmlElement objElement = (XmlElement)objItem;
                                                        objElement.SetAttribute("translate", objSpec.Attributes["translate"].InnerXml);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    // Check for Metavariant information.
                                    if (strFileName == "metatypes.xml")
                                    {
                                        if (objChild["metavariants"] != null)
                                        {
                                            foreach (XmlNode objMetavariant in objChild.SelectNodes("metavariants/metavariant"))
                                            {
                                                if (objMetavariant["translate"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + objChild["name"].InnerXml + "\"]/metavariants/metavariant[name = \"" + objMetavariant["name"].InnerXml + "\"]");
                                                    if (objItem != null)
                                                        objItem.InnerXml += "<translate>" + objMetavariant["translate"].InnerXml + "</translate>";
                                                }
                                                if (objMetavariant["altpage"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + objChild["name"].InnerXml + "\"]/metavariants/metavariant[name = \"" + objMetavariant["name"].InnerXml + "\"]");
                                                    if (objItem != null)
                                                        objItem.InnerXml += "<altpage>" + objMetavariant["page"].InnerXml + "</altpage>";
                                                }
                                            }
                                        }
                                    }

                                    // Check for Martial Art Advantage information.
                                    if (strFileName == "martialarts.xml")
                                    {
                                        if (objChild["advantages"] != null)
                                        {
                                            foreach (XmlNode objAdvantage in objChild.SelectNodes("techniques/technique"))
                                            {
                                                if (objAdvantage.Attributes["translate"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/martialarts/martialart[name = \"" + objChild["name"].InnerXml + "\"]/techniques/technique[. = \"" + objAdvantage.InnerXml + "\"]");
                                                    if (objItem != null)
                                                    {
                                                        XmlElement objElement = (XmlElement)objItem;
                                                        objElement.SetAttribute("translate", objAdvantage.Attributes["translate"].InnerXml);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    // Check for Mentor Spirit/Paragon choice information.
                                    if (strFileName == "mentors.xml" || strFileName == "paragons.xml")
                                    {
                                        if (objChild["choices"] != null)
                                        {
                                            foreach (XmlNode objChoice in objChild.SelectNodes("choices/choice"))
                                            {
                                                if (objChoice["translate"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/mentors/mentor[name = \"" + objChild["name"].InnerXml + "\"]/choices/choice[name = \"" + objChoice["name"].InnerXml + "\"]");
                                                    if (objItem != null)
                                                        objItem.InnerXml += "<translate>" + objChoice["translate"].InnerXml + "</translate>";
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // Cache the merged document and its relevant information.
                objReference.FileDate = datDate;
                objReference.FileName = strFileName;
                objReference.XmlContent = objDoc;
            }
            else
            {
                // Pull the document from cache.
                objDoc = objReference.XmlContent;
            }

            // A new XmlDocument is created by loading the a copy of the cached one so that we don't stuff custom content into the cached copy
            // (which we don't want and also results in multiple copies of each custom item).
            XmlDocument objReturnDocument = new XmlDocument();
            objReturnDocument.LoadXml(objDoc.OuterXml);

            // Load any custom data files the user might have. Do not attempt this if we're loading the Improvements file.
            if (strFileName != "improvements.xml")
            {
                strPath = Path.Combine(Environment.CurrentDirectory, "data");
                foreach (string strFile in Directory.GetFiles(strPath, "custom*_" + strFileName))
                {
                    objXmlFile.Load(strFile);
                    objList = objXmlFile.SelectNodes("/chummer/*");
                    foreach (XmlNode objNode in objList)
                    {
                        // Look for any items with a duplicate name and pluck them from the node so we don't end up with multiple items with the same name.
                        List<XmlNode> lstDelete = new List<XmlNode>();
                        foreach (XmlNode objChild in objNode.ChildNodes)
                        {
                            // Only do this if the child has the name field since this is what we must match on.
                            if (objChild["name"] != null)
                            {
                                XmlNodeList objNodeList = objReturnDocument.SelectNodes("/chummer/" + objChild.ParentNode.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerText + "\"]");
                                if (objNodeList.Count > 0)
                                {
                                    lstDelete.Add(objChild);
                                }
                            }
                        }
                        // Remove the offending items from the node we're about to merge in.
                        foreach (XmlNode objRemoveNode in lstDelete)
                        {
                            objNode.RemoveChild(objRemoveNode);
                        }

                        // Append the entire child node to the new document.
                        XmlNode objImported = objReturnDocument.ImportNode(objNode, true);
                        objReturnDocument.DocumentElement.AppendChild(objImported);
                    }
                }
            }

            return objReturnDocument;
        }
Example #3
0
        /// <summary>
        /// Load the selected XML file and its associated custom file.
        /// </summary>
        /// <param name="strFileName">Name of the XML file to load.</param>
        public XmlDocument Load(string strFileName)
        {
            string   strPath = Path.Combine(Environment.CurrentDirectory, "data", strFileName);
            DateTime datDate = File.GetLastWriteTime(strPath);

            // Look to see if this XmlDocument is already loaded.
            bool         blnFound     = false;
            XmlReference objReference = new XmlReference();

            foreach (XmlReference objCurrentReference in _lstXmlDocuments)
            {
                if (objCurrentReference.FileName == strFileName)
                {
                    objReference = objCurrentReference;
                    blnFound     = true;
                    break;
                }
            }

            bool blnLoadFile = false;

            if (!blnFound)
            {
                // The file was not found in the reference list, so it must be loaded.
                blnLoadFile = true;
                _lstXmlDocuments.Add(objReference);
            }
            else
            {
                // The file was found in the List, so check the last write time.
                if (datDate != objReference.FileDate)
                {
                    // The last write time does not match, so it must be reloaded.
                    blnLoadFile = true;
                }
            }

            // Create a new document that everything will be merged into.
            XmlDocument objDoc = new XmlDocument();
            // write the root chummer node.
            XmlNode objCont = objDoc.CreateElement("chummer");

            objDoc.AppendChild(objCont);

            XmlDocument objXmlFile = new XmlDocument();
            XmlNodeList objList;

            if (blnLoadFile)
            {
                // Load the base file and retrieve all of the child nodes.
                objXmlFile.Load(strPath);
                objList = objXmlFile.SelectNodes("/chummer/*");
                foreach (XmlNode objNode in objList)
                {
                    // Append the entire child node to the new document.
                    XmlNode objImported = objDoc.ImportNode(objNode, true);
                    objDoc.DocumentElement.AppendChild(objImported);
                }

                // Load any override data files the user might have. Do not attempt this if we're loading the Improvements file.
                if (strFileName != "improvements.xml")
                {
                    string strFilePath = Path.Combine(Environment.CurrentDirectory, "data");
                    foreach (string strFile in Directory.GetFiles(strFilePath, "override*_" + strFileName))
                    {
                        objXmlFile.Load(strFile);
                        objList = objXmlFile.SelectNodes("/chummer/*");
                        foreach (XmlNode objNode in objList)
                        {
                            foreach (XmlNode objType in objNode.ChildNodes)
                            {
                                if (objType["name"] != null)
                                {
                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objNode.Name + "/" + objType.Name + "[name = \"" + objType["name"].InnerText.Replace("&amp;", "&") + "\"]");
                                    if (objItem != null)
                                    {
                                        objItem.InnerXml = objType.InnerXml;
                                    }
                                }
                            }
                        }
                    }
                }

                // Load the translation file for the current base data file if the selected language is not en-us.
                if (GlobalOptions.Instance.Language != "en-us")
                {
                    // Everything is stored in the selected language file to make translations easier, keep all of the language-specific information together, and not require users to download 27 individual files.
                    // The structure is similar to the base data file, but the root node is instead a child /chummer node with a file attribute to indicate the XML file it translates.
                    if (LanguageManager.Instance.DataDoc != null)
                    {
                        foreach (XmlNode objNode in LanguageManager.Instance.DataDoc.SelectNodes("/chummer/chummer[@file = \"" + strFileName + "\"]"))
                        {
                            foreach (XmlNode objType in objNode.ChildNodes)
                            {
                                foreach (XmlNode objChild in objType.ChildNodes)
                                {
                                    // If this is a translatable item, find the proper node and add/update this information.
                                    if (objChild["translate"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                        {
                                            objItem.InnerXml += "<translate>" + objChild["translate"].InnerXml + "</translate>";
                                        }
                                    }
                                    if (objChild["page"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                        {
                                            objItem.InnerXml += "<altpage>" + objChild["page"].InnerXml + "</altpage>";
                                        }
                                    }
                                    if (objChild["code"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                        {
                                            objItem.InnerXml += "<altcode>" + objChild["code"].InnerXml + "</altcode>";
                                        }
                                    }
                                    if (objChild["advantage"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                        {
                                            objItem.InnerXml += "<altadvantage>" + objChild["advantage"].InnerXml + "</altadvantage>";
                                        }
                                    }
                                    if (objChild["disadvantage"] != null)
                                    {
                                        XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                        {
                                            objItem.InnerXml += "<altdisadvantage>" + objChild["disadvantage"].InnerXml + "</altdisadvantage>";
                                        }
                                    }
                                    if (objChild.Attributes != null)
                                    {
                                        // Handle Category name translations.
                                        if (objChild.Attributes["translate"] != null)
                                        {
                                            XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[. = \"" + objChild.InnerXml.Replace("&amp;", "&") + "\"]");
                                            if (objItem != null)
                                            {
                                                XmlElement objElement = (XmlElement)objItem;
                                                objElement.SetAttribute("translate", objChild.Attributes["translate"].InnerXml);
                                            }
                                        }
                                    }

                                    // Check for Skill Specialization information.
                                    if (strFileName == "skills.xml")
                                    {
                                        if (objChild["specs"] != null)
                                        {
                                            foreach (XmlNode objSpec in objChild.SelectNodes("specs/spec"))
                                            {
                                                if (objSpec.Attributes["translate"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/skill[name = \"" + objChild["name"].InnerXml + "\"]/specs/spec[. = \"" + objSpec.InnerXml + "\"]");
                                                    if (objItem != null)
                                                    {
                                                        XmlElement objElement = (XmlElement)objItem;
                                                        objElement.SetAttribute("translate", objSpec.Attributes["translate"].InnerXml);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    // Check for Metavariant information.
                                    if (strFileName == "metatypes.xml")
                                    {
                                        if (objChild["metavariants"] != null)
                                        {
                                            foreach (XmlNode objMetavariant in objChild.SelectNodes("metavariants/metavariant"))
                                            {
                                                if (objMetavariant["translate"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + objChild["name"].InnerXml + "\"]/metavariants/metavariant[name = \"" + objMetavariant["name"].InnerXml + "\"]");
                                                    if (objItem != null)
                                                    {
                                                        objItem.InnerXml += "<translate>" + objMetavariant["translate"].InnerXml + "</translate>";
                                                    }
                                                }
                                                if (objMetavariant["altpage"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + objChild["name"].InnerXml + "\"]/metavariants/metavariant[name = \"" + objMetavariant["name"].InnerXml + "\"]");
                                                    if (objItem != null)
                                                    {
                                                        objItem.InnerXml += "<altpage>" + objMetavariant["page"].InnerXml + "</altpage>";
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    // Check for Martial Art Advantage information.
                                    if (strFileName == "martialarts.xml")
                                    {
                                        if (objChild["advantages"] != null)
                                        {
                                            foreach (XmlNode objAdvantage in objChild.SelectNodes("techniques/technique"))
                                            {
                                                if (objAdvantage.Attributes["translate"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/martialarts/martialart[name = \"" + objChild["name"].InnerXml + "\"]/techniques/technique[. = \"" + objAdvantage.InnerXml + "\"]");
                                                    if (objItem != null)
                                                    {
                                                        XmlElement objElement = (XmlElement)objItem;
                                                        objElement.SetAttribute("translate", objAdvantage.Attributes["translate"].InnerXml);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    // Check for Mentor Spirit/Paragon choice information.
                                    if (strFileName == "mentors.xml" || strFileName == "paragons.xml")
                                    {
                                        if (objChild["choices"] != null)
                                        {
                                            foreach (XmlNode objChoice in objChild.SelectNodes("choices/choice"))
                                            {
                                                if (objChoice["translate"] != null)
                                                {
                                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/mentors/mentor[name = \"" + objChild["name"].InnerXml + "\"]/choices/choice[name = \"" + objChoice["name"].InnerXml + "\"]");
                                                    if (objItem != null)
                                                    {
                                                        objItem.InnerXml += "<translate>" + objChoice["translate"].InnerXml + "</translate>";
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // Cache the merged document and its relevant information.
                objReference.FileDate   = datDate;
                objReference.FileName   = strFileName;
                objReference.XmlContent = objDoc;
            }
            else
            {
                // Pull the document from cache.
                objDoc = objReference.XmlContent;
            }

            // A new XmlDocument is created by loading the a copy of the cached one so that we don't stuff custom content into the cached copy
            // (which we don't want and also results in multiple copies of each custom item).
            XmlDocument objReturnDocument = new XmlDocument();

            objReturnDocument.LoadXml(objDoc.OuterXml);

            // Load any custom data files the user might have. Do not attempt this if we're loading the Improvements file.
            if (strFileName != "improvements.xml")
            {
                strPath = Path.Combine(Environment.CurrentDirectory, "data");
                foreach (string strFile in Directory.GetFiles(strPath, "custom*_" + strFileName))
                {
                    objXmlFile.Load(strFile);
                    objList = objXmlFile.SelectNodes("/chummer/*");
                    foreach (XmlNode objNode in objList)
                    {
                        // Look for any items with a duplicate name and pluck them from the node so we don't end up with multiple items with the same name.
                        List <XmlNode> lstDelete = new List <XmlNode>();
                        foreach (XmlNode objChild in objNode.ChildNodes)
                        {
                            // Only do this if the child has the name field since this is what we must match on.
                            if (objChild["name"] != null)
                            {
                                XmlNodeList objNodeList = objReturnDocument.SelectNodes("/chummer/" + objChild.ParentNode.Name + "/" + objChild.Name + "[name = \"" + objChild["name"].InnerText + "\"]");
                                if (objNodeList.Count > 0)
                                {
                                    lstDelete.Add(objChild);
                                }
                            }
                        }
                        // Remove the offending items from the node we're about to merge in.
                        foreach (XmlNode objRemoveNode in lstDelete)
                        {
                            objNode.RemoveChild(objRemoveNode);
                        }

                        // Append the entire child node to the new document.
                        XmlNode objImported = objReturnDocument.ImportNode(objNode, true);
                        objReturnDocument.DocumentElement.AppendChild(objImported);
                    }
                }
            }

            return(objReturnDocument);
        }
Example #4
0
        /// <summary>
        /// Load the selected XML file and its associated custom file.
        /// </summary>
        /// <param name="strFileName">Name of the XML file to load.</param>
        /// <param name="blnLoadFile">Whether to force reloading content even if the file already exists.</param>
        public XmlDocument Load(string strFileName, bool blnLoadFile = false)
        {
            string strPath = Path.Combine(Application.StartupPath, "data", strFileName);

            if (!File.Exists(strPath))
            {
                Utils.BreakIfDebug();
                return(null);
            }
            DateTime datDate = File.GetLastWriteTime(strPath);

            // Look to see if this XmlDocument is already loaded.
            XmlReference objReference = _lstXmlDocuments.Find(x => x.FileName == strFileName);

            if (objReference == null || blnLoadFile)
            {
                // The file was not found in the reference list, so it must be loaded.
                objReference = new XmlReference();
                blnLoadFile  = true;
                _lstXmlDocuments.Add(objReference);
            }
            // The file was found in the List, so check the last write time.
            else if (datDate != objReference.FileDate)
            {
                // The last write time does not match, so it must be reloaded.
                blnLoadFile = true;
            }

            // Create a new document that everything will be merged into.
            XmlDocument objDoc;
            XmlDocument objXmlFile = new XmlDocument();

            if (blnLoadFile)
            {
                objDoc = new XmlDocument();
                // write the root chummer node.
                XmlNode objCont = objDoc.CreateElement("chummer");
                objDoc.AppendChild(objCont);
                // Load the base file and retrieve all of the child nodes.
                objXmlFile.Load(strPath);
                XmlNodeList xmlNodeList = objXmlFile.SelectNodes("/chummer/*");
                if (xmlNodeList != null)
                {
                    foreach (XmlNode objNode in xmlNodeList)
                    {
                        // Append the entire child node to the new document.
                        objDoc.DocumentElement.AppendChild(objDoc.ImportNode(objNode, true));
                    }
                }

                // Load any override data files the user might have. Do not attempt this if we're loading the Improvements file.
                if (strFileName != "improvements.xml")
                {
                    strPath = Path.Combine(Application.StartupPath, "data");
                    foreach (string strFile in Directory.GetFiles(strPath, "override*_" + strFileName))
                    {
                        objXmlFile.Load(strFile);
                        foreach (XmlNode objNode in objXmlFile.SelectNodes("/chummer/*"))
                        {
                            foreach (XmlNode objType in objNode.ChildNodes)
                            {
                                if (objType["id"] != null)
                                {
                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objNode.Name + "/" + objType.Name + "[id = \"" + objType["id"].InnerText.Replace("&amp;", "&") + "\"]");
                                    if (objItem != null)
                                    {
                                        objItem.InnerXml = objType.InnerXml;
                                    }
                                }
                                else if (objType["name"] != null)
                                {
                                    XmlNode objItem = objDoc.SelectSingleNode("/chummer/" + objNode.Name + "/" + objType.Name + "[name = \"" + objType["name"].InnerText.Replace("&amp;", "&") + "\"]");
                                    if (objItem != null)
                                    {
                                        objItem.InnerXml = objType.InnerXml;
                                    }
                                }
                            }
                        }
                    }

                    // Load any custom data files the user might have. Do not attempt this if we're loading the Improvements file.
                    foreach (string strFile in Directory.GetFiles(strPath, "custom*_" + strFileName))
                    {
                        objXmlFile.Load(strFile);
                        foreach (XmlNode objNode in objXmlFile.SelectNodes("/chummer/*"))
                        {
                            // Look for any items with a duplicate name and pluck them from the node so we don't end up with multiple items with the same name.
                            List <XmlNode> lstDelete = new List <XmlNode>();
                            foreach (XmlNode objChild in objNode.ChildNodes)
                            {
                                if (objChild.ParentNode != null)
                                {
                                    // Only do this if the child has the name or id field since this is what we must match on.
                                    if (objChild["id"] != null && null != objDoc.SelectSingleNode("/chummer/" + objChild.ParentNode.Name + "/" +
                                                                                                  objChild.Name + "[name = \"" +
                                                                                                  objChild["id"].InnerText + "\"]"))
                                    {
                                        lstDelete.Add(objChild);
                                    }
                                    else if (objChild["name"] != null && null != objDoc.SelectSingleNode("/chummer/" + objChild.ParentNode.Name + "/" +
                                                                                                         objChild.Name + "[name = \"" +
                                                                                                         objChild["name"].InnerText + "\"]"))
                                    {
                                        lstDelete.Add(objChild);
                                    }
                                }
                            }
                            // Remove the offending items from the node we're about to merge in.
                            foreach (XmlNode objRemoveNode in lstDelete)
                            {
                                objNode.RemoveChild(objRemoveNode);
                            }

                            // Append the entire child node to the new document.
                            objDoc.DocumentElement?.AppendChild(objDoc.ImportNode(objNode, true));
                        }
                    }
                }

                // Load the translation file for the current base data file if the selected language is not en-us.
                if (GlobalOptions.Instance.Language != "en-us")
                {
                    // Everything is stored in the selected language file to make translations easier, keep all of the language-specific information together, and not require users to download 27 individual files.
                    // The structure is similar to the base data file, but the root node is instead a child /chummer node with a file attribute to indicate the XML file it translates.
                    if (LanguageManager.Instance.DataDoc != null)
                    {
                        foreach (XmlNode objNode in LanguageManager.Instance.DataDoc.SelectNodes("/chummer/chummer[@file = \"" + strFileName + "\"]"))
                        {
                            foreach (XmlNode objType in objNode.ChildNodes)
                            {
                                foreach (XmlNode objChild in objType.ChildNodes)
                                {
                                    if (objChild["name"] != null)
                                    {
                                        // If this is a translatable item, find the proper node and add/update this information.
                                        XmlNode objItem =
                                            objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[name = \"" +
                                                                    objChild["name"].InnerXml.Replace("&amp;", "&") + "\"]");
                                        if (objItem != null)
                                        {
                                            if (objChild["translate"] != null)
                                            {
                                                objItem.InnerXml += "<translate>" + objChild["translate"].InnerXml + "</translate>";
                                            }
                                            if (objChild["page"] != null)
                                            {
                                                objItem.InnerXml += "<altpage>" + objChild["page"].InnerXml + "</altpage>";
                                            }
                                            if (objChild["code"] != null)
                                            {
                                                objItem.InnerXml += "<altcode>" + objChild["code"].InnerXml + "</altcode>";
                                            }
                                            if (objChild["advantage"] != null)
                                            {
                                                objItem.InnerXml += "<altadvantage>" + objChild["advantage"].InnerXml + "</altadvantage>";
                                            }
                                            if (objChild["disadvantage"] != null)
                                            {
                                                objItem.InnerXml += "<altdisadvantage>" + objChild["disadvantage"].InnerXml + "</altdisadvantage>";
                                            }
                                            if (objChild.Attributes?["translate"] != null)
                                            {
                                                // Handle Category name translations.
                                                (objItem as XmlElement)?.SetAttribute("translate", objChild.Attributes["translate"].InnerXml);
                                            }

                                            // Check for Skill Specialization information.
                                            if (strFileName == "skills.xml")
                                            {
                                                if (objChild["specs"] != null)
                                                {
                                                    foreach (XmlNode objSpec in objChild.SelectNodes("specs/spec"))
                                                    {
                                                        if (objSpec.Attributes?["translate"] != null)
                                                        {
                                                            XmlElement objSpecItem = objItem.SelectSingleNode("specs/spec[. = \"" + objSpec.InnerXml + "\"]") as XmlElement;
                                                            objSpecItem?.SetAttribute("translate", objSpec.Attributes["translate"].InnerXml);
                                                        }
                                                    }
                                                }
                                            }
                                            // Check for Metavariant information.
                                            else if (strFileName == "metatypes.xml")
                                            {
                                                if (objChild["metavariants"] != null)
                                                {
                                                    foreach (XmlNode objMetavariant in objChild.SelectNodes("metavariants/metavariant"))
                                                    {
                                                        if (objMetavariant["name"] != null && objChild["name"] != null)
                                                        {
                                                            XmlNode objMetavariantItem =
                                                                objDoc.SelectSingleNode(
                                                                    "/chummer/metatypes/metatype[name = \"" +
                                                                    objChild["name"].InnerXml +
                                                                    "\"]/metavariants/metavariant[name = \"" +
                                                                    objMetavariant["name"].InnerXml + "\"]");
                                                            if (objMetavariantItem != null)
                                                            {
                                                                if (objMetavariant["translate"] != null)
                                                                {
                                                                    objMetavariantItem.InnerXml += "<translate>" +
                                                                                                   objMetavariant[
                                                                        "translate"].InnerXml +
                                                                                                   "</translate>";
                                                                }
                                                                if (objMetavariant["page"] != null)
                                                                {
                                                                    objMetavariantItem.InnerXml += "<altpage>" +
                                                                                                   objMetavariant["page"]
                                                                                                   .InnerXml +
                                                                                                   "</altpage>";
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            // Check for Martial Art Advantage information.
                                            else if (strFileName == "martialarts.xml")
                                            {
                                                if (objChild["advantages"] != null)
                                                {
                                                    foreach (XmlNode objAdvantage in objChild.SelectNodes("techniques/technique"))
                                                    {
                                                        if (objAdvantage.Attributes?["translate"] != null)
                                                        {
                                                            XmlElement objAdvantageItem = objItem.SelectSingleNode("techniques/technique[. = \"" + objAdvantage.InnerXml + "\"]") as XmlElement;
                                                            objAdvantageItem?.SetAttribute("translate", objAdvantage.Attributes["translate"].InnerXml);
                                                        }
                                                    }
                                                }
                                            }
                                            // Check for Mentor Spirit/Paragon choice information.
                                            else if (strFileName == "mentors.xml" || strFileName == "paragons.xml")
                                            {
                                                if (objChild["choices"] != null)
                                                {
                                                    foreach (XmlNode objChoice in objChild.SelectNodes("choices/choice"))
                                                    {
                                                        if (objChoice["name"] != null && objChoice["translate"] != null)
                                                        {
                                                            XmlNode objChoiceItem = objItem.SelectSingleNode("choices/choice[name = \"" + objChoice["name"].InnerXml + "\"]");
                                                            if (objChoiceItem != null)
                                                            {
                                                                objChoiceItem.InnerXml += "<translate>" + objChoice["translate"].InnerXml + "</translate>";
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    else if (objChild.Attributes?["translate"] != null)
                                    {
                                        // Handle Category name translations.
                                        XmlElement objItem = objDoc.SelectSingleNode("/chummer/" + objType.Name + "/" + objChild.Name + "[. = \"" + objChild.InnerXml.Replace("&amp;", "&") + "\"]") as XmlElement;
                                        // Expected result is null if not found.
                                        objItem?.SetAttribute("translate", objChild.Attributes["translate"].InnerXml);
                                    }
                                }
                            }
                        }
                    }
                }

                // Cache the merged document and its relevant information.
                objReference.FileDate = datDate;
                objReference.FileName = strFileName;
                if (GlobalOptions.Instance.LiveCustomData)
                {
                    objReference.XmlContent = objDoc.Clone() as XmlDocument;
                }
                else
                {
                    objReference.XmlContent = objDoc;
                }
            }
            else
            {
                // A new XmlDocument is created by loading the a copy of the cached one so that we don't stuff custom content into the cached copy
                // (which we don't want and also results in multiple copies of each custom item).
                // Pull the document from cache.
                if (GlobalOptions.Instance.LiveCustomData)
                {
                    objDoc = objReference.XmlContent.Clone() as XmlDocument;
                }
                else
                {
                    objDoc = objReference.XmlContent;
                }
            }

            // Load any custom data files the user might have. Do not attempt this if we're loading the Improvements file.
            if (GlobalOptions.Instance.LiveCustomData && objDoc != null && strFileName != "improvements.xml")
            {
                strPath = Path.Combine(Application.StartupPath, "customdata");
                if (Directory.Exists(strPath))
                {
                    foreach (string strFile in Directory.GetFiles(strPath, "custom*_" + strFileName))
                    {
                        objXmlFile.Load(strFile);
                        foreach (XmlNode objNode in objXmlFile.SelectNodes("/chummer/*"))
                        {
                            // Look for any items with a duplicate name and pluck them from the node so we don't end up with multiple items with the same name.
                            List <XmlNode> lstDelete = new List <XmlNode>();
                            foreach (XmlNode objChild in objNode.ChildNodes)
                            {
                                // Only do this if the child has the name or id field since this is what we must match on.
                                if (objChild["id"] != null &&
                                    null != objDoc.SelectSingleNode("/chummer/" + objChild.ParentNode.Name + "/" +
                                                                    objChild.Name + "[name = \"" +
                                                                    objChild["id"].InnerText + "\"]"))
                                {
                                    lstDelete.Add(objChild);
                                }
                                else if (objChild["name"] != null &&
                                         null != objDoc.SelectSingleNode("/chummer/" + objChild.ParentNode.Name + "/" +
                                                                         objChild.Name + "[name = \"" +
                                                                         objChild["name"].InnerText + "\"]"))
                                {
                                    lstDelete.Add(objChild);
                                }
                            }
                            // Remove the offending items from the node we're about to merge in.
                            foreach (XmlNode objRemoveNode in lstDelete)
                            {
                                objNode.RemoveChild(objRemoveNode);
                            }

                            // Append the entire child node to the new document.
                            objDoc.DocumentElement?.AppendChild(objDoc.ImportNode(objNode, true));
                        }
                    }
                }
            }

            //Check for non-unique guids in the loaded XML file. Ignore improvements.xml since the ids are used in a different way.
            if (strFileName == "improvements.xml" || objReference.DuplicatesChecked)
            {
                return(objDoc);
            }
            {
                foreach (XmlNode objNode in objDoc.SelectNodes("/chummer/*"))
                {
                    //Ignore the version node, if present.
                    if (objNode.Name == "version" || !objNode.HasChildNodes)
                    {
                        continue;
                    }
                    //Parse the node into an XDocument for LINQ parsing.
                    XDocument y       = XDocument.Parse(objNode.OuterXml);
                    string    strNode = (from XmlNode o in objNode.ChildNodes where o.NodeType != XmlNodeType.Comment select o.Name).FirstOrDefault();

                    //Grab the first XML node that isn't a comment.
                    if (strNode == null)
                    {
                        continue;
                    }
                    var duplicatesList = y.Descendants(strNode)
                                         .GroupBy(g => (string)g.Element("id") ?? "")
                                         .Where(g => g.Count() > 1)
                                         .Select(g => g.Key)
                                         .ToList();
                    int i = duplicatesList.Count(o => !string.IsNullOrWhiteSpace(o));
                    if (i <= 0)
                    {
                        objReference.DuplicatesChecked = true;
                        continue;
                    }
                    string duplicates = string.Join("\n", duplicatesList);
                    MessageBox.Show(
                        LanguageManager.Instance.GetString("Message_DuplicateGuidWarning")
                        .Replace("{0}", i.ToString())
                        .Replace("{1}", strFileName)
                        .Replace("{2}", duplicates));
                }
            }

            return(objDoc);
        }