Exemple #1
0
        /// <summary>
        /// Resolves the shortcut on the specified node. i.e. makes concrete
        /// </summary>
        /// <param name="node">The node to remove the shortcut from.</param>
        /// <exception cref="System.Exception">Cannot find shortcut:  + shortcut</exception>
        private static void ResolveShortcut(XmlNode node)
        {
            string  shortcut     = XmlUtilities.Attribute(node, "shortcut");
            XmlNode concreteNode = XmlUtilities.Find(node.OwnerDocument.DocumentElement, shortcut);

            if (concreteNode == null)
            {
                throw new Exception("Cannot find shortcut: " + shortcut);
            }

            foreach (XmlNode child in concreteNode.ChildNodes)
            {
                // Get the 'name' of the concrete child
                string childName = XmlUtilities.NameAttr(child);
                if (childName == string.Empty)
                {
                    childName = child.Name;
                }

                // See if we have a node under shortcutted node with same name as concrete node.
                XmlNode nodeToReplace = XmlUtilities.Find(node, childName);
                if (nodeToReplace == null)
                {
                    node.AppendChild(child.Clone());
                }
                else
                {
                    // Only replace non shortcutted child nodes.
                    if (XmlUtilities.Attribute(nodeToReplace, "shortcut") == string.Empty)
                    {
                        nodeToReplace.ParentNode.ReplaceChild(child.Clone(), nodeToReplace);
                    }
                }
            }
        }
Exemple #2
0
        private static void DocumentNode(StreamWriter OutputFile, XmlNode N, int NextLevel, Model parentModel)
        {
            if (N.Name == "Name")
            {
                return;
            }

            if (XmlUtilities.Attribute(N, "shortcut") != "")
            {
                OutputFile.WriteLine("<p>" + XmlUtilities.Value(N, "Name") + " uses the same value as " + XmlUtilities.Attribute(N, "shortcut"));
            }
            else if (N.Name == "Constant")
            {
                OutputFile.WriteLine(Header(XmlUtilities.Value(N, "Name"), NextLevel, XmlUtilities.Value(N.ParentNode, "Name")));

                WriteDescriptionForTypeName(OutputFile, N, parentModel);
                TryDocumentMemo(OutputFile, N, NextLevel);

                OutputFile.WriteLine("<p>Value = " + XmlUtilities.Value(N, "Value") + "</p>");
            }
            else if (XmlUtilities.ChildNodes(N, "").Count == 0)
            {
                WriteDescriptionForTypeName(OutputFile, N, parentModel);

                DocumentProperty(OutputFile, N, NextLevel);
            }
            else if (XmlUtilities.ChildNodes(N, "XYPairs").Count > 0)
            {
                CreateGraph(OutputFile, XmlUtilities.ChildNodes(N, "XYPairs")[0], NextLevel, parentModel);
            }
            else if (XmlUtilities.Type(N) == "TemperatureFunction")
            {
                DocumentTemperatureFunction(OutputFile, N, NextLevel, parentModel);
            }
            //else if (XmlUtilities.Type(N) == "GenericPhase")
            //   DocumentFixedPhase(OutputFile, N, NextLevel);
            // else if (XmlUtilities.Type(N) == "PhaseLookupValue")
            //   DocumentPhaseLookupValue(OutputFile, N, NextLevel);
            else if (XmlUtilities.Type(N) == "ChillingPhase")
            {
                ChillingPhaseFunction(OutputFile, N, NextLevel);
            }
            else if (N.Name == "Memo")
            {
                DocumentMemo(OutputFile, N, NextLevel);
            }
            else
            {
                string childName  = XmlUtilities.Value(N, "Name");
                Model  childModel = null;
                if (parentModel != null)
                {
                    childModel = Apsim.Child(parentModel, childName) as Model;
                }
                DocumentNodeAndChildren(OutputFile, N, NextLevel, childModel);
            }
        }
Exemple #3
0
        /// <summary>
        /// Removes all shortcuts from the specified node and all child nodes.
        /// </summary>
        /// <param name="node">The node to remove shortcuts from.</param>
        /// <returns>The XML node with all shortcuts resolved.</returns>
        public static void Remove(XmlNode node)
        {
            string shortcut = XmlUtilities.Attribute(node, "shortcut");

            if (shortcut != string.Empty)
            {
                ResolveShortcut(node);
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                Remove(child);   // recursion
            }
        }
Exemple #4
0
 /// <summary>Finds a direct child of the specified node that has a name starting with a prefix.</summary>
 /// <param name="node">The node.</param>
 /// <param name="namePrefix">The beginning of a name attribute to find.</param>
 /// <returns></returns>
 private static XmlNode FindChildWithPrefix(XmlNode node, string namePrefix)
 {
     if (node != null)
     {
         foreach (XmlNode child in node.ChildNodes)
         {
             var name = XmlUtilities.Attribute(child, "name");
             if (name != null && name.StartsWith(namePrefix))
             {
                 return(child);
             }
         }
     }
     return(null);
 }
Exemple #5
0
        /// <summary>
        /// Resolves the shortcut on the specified node. i.e. makes concrete
        /// </summary>
        /// <param name="node">The node to remove the shortcut from.</param>
        /// <exception cref="System.Exception">Cannot find shortcut:  + shortcut</exception>
        private static void ResolveShortcut(XmlNode node)
        {
            string  shortcut     = XmlUtilities.Attribute(node, "shortcut");
            XmlNode concreteNode = XmlUtilities.Find(node.OwnerDocument.DocumentElement, shortcut);

            if (concreteNode == null)
            {
                throw new Exception("Cannot find shortcut: " + shortcut);
            }

            if (!string.IsNullOrWhiteSpace(XmlUtilities.Attribute(concreteNode, "shortcut")))
            {
                // If this happens, the node we are linked to is a shortcut
                // itself and is further down in the simulations tree than the
                // current node. In this scenario, we want to resolve the link
                // and remove the shortcut attribute so we don't resolve the
                // shortcut a second time in the Remove() method.
                ResolveShortcut(concreteNode);
                XmlUtilities.DeleteAttribute(concreteNode, "shortcut");
            }

            foreach (XmlNode child in concreteNode.ChildNodes)
            {
                // Get the 'name' of the concrete child
                string childName = XmlUtilities.NameAttr(child);
                if (childName == string.Empty)
                {
                    childName = child.Name;
                }

                // See if we have a node under shortcutted node with same name as concrete node.
                XmlNode nodeToReplace = XmlUtilities.Find(node, childName);
                if (nodeToReplace == null)
                {
                    node.AppendChild(child.Clone());
                }
                else
                {
                    // Only replace non shortcutted child nodes.
                    if (XmlUtilities.Attribute(nodeToReplace, "shortcut") == string.Empty)
                    {
                        nodeToReplace.ParentNode.ReplaceChild(child.Clone(), nodeToReplace);
                    }
                }
            }
        }
Exemple #6
0
        /// <summary>Constructor for a genotype from ruminant.prm.</summary>
        /// <param name="parameterNode">The ruminant.prm xml node where this genotype is defined.</param>
        public GenotypeWrapper(XmlNode parameterNode)
        {
            parameterXmlSections.Add(parameterNode.OuterXml);
            var parent = parameterNode.ParentNode;

            while (!(parent is XmlDocument))
            {
                parameterXmlSections.Add(parent.OuterXml);
                parent = parent.ParentNode;
            }

            Name       = XmlUtilities.Attribute(parameterNode, "name").Replace(".", "");
            AnimalType = XmlUtilities.Value(parameterNode, "animal");
            var parentNode = parameterNode.ParentNode;

            while (AnimalType == string.Empty && parentNode != null)
            {
                AnimalType = XmlUtilities.Value(parentNode, "animal");
                parentNode = parentNode.ParentNode;
            }
        }
Exemple #7
0
        /// <summary>Converts XML to the latest version.</summary>
        /// <param name="rootNode">The root node.</param>
        /// <param name="fileName">The name of the .apsimx file</param>
        /// <returns>Returns true if something was changed.</returns>
        public static bool ConvertToLatestVersion(XmlNode rootNode, string fileName)
        {
            string fileVersionString = XmlUtilities.Attribute(rootNode, "Version");
            int    fileVersion       = 0;

            if (fileVersionString != string.Empty)
            {
                fileVersion = Convert.ToInt32(fileVersionString);
            }

            // Update the xml if not at the latest version.
            bool changed = false;

            while (fileVersion < LastestVersion)
            {
                changed = true;

                // Find the method to call to upgrade the file by one version.
                int        toVersion = fileVersion + 1;
                MethodInfo method    = typeof(APSIMFileConverter).GetMethod("UpgradeToVersion" + toVersion, BindingFlags.NonPublic | BindingFlags.Static);
                if (method == null)
                {
                    throw new Exception("Cannot find converter to go to version " + toVersion);
                }

                // Found converter method so call it.
                method.Invoke(null, new object[] { rootNode, fileName });

                fileVersion++;
            }

            if (changed)
            {
                XmlUtilities.SetAttribute(rootNode, "Version", fileVersion.ToString());
            }
            return(changed);
        }
        /// <summary>Sets the soil.</summary>
        /// <param name="soil">The soil.</param>
        public void SetSoil(Soil soil)
        {
            XmlDocument soilDoc = new XmlDocument();

            soilDoc.LoadXml(SoilUtilities.ToXML(soil));

            // Name soil crop models
            foreach (XmlNode soilcrop in XmlUtilities.FindAllRecursivelyByType(soilDoc.DocumentElement, "SoilCrop"))
            {
                XmlUtilities.SetValue(soilcrop, "Name", XmlUtilities.Attribute(soilcrop, "name") + "Soil");
            }

            // Name soil samples
            foreach (XmlNode sample in XmlUtilities.FindAllRecursivelyByType(soilDoc.DocumentElement, "Sample"))
            {
                XmlUtilities.SetValue(sample, "Name", XmlUtilities.Attribute(sample, "name"));
            }

            XmlNode paddockNode = XmlUtilities.Find(simulationXML, "Zone");

            XmlUtilities.EnsureNodeExists(soilDoc.DocumentElement, "SoilNitrogen");
            soilDoc.DocumentElement.RemoveChild(XmlUtilities.Find(soilDoc.DocumentElement, "SoilTemperature"));
            paddockNode.AppendChild(paddockNode.OwnerDocument.ImportNode(soilDoc.DocumentElement, true));
        }
Exemple #9
0
        /// <summary>
        /// Pastes the contents of the clipboard.
        /// </summary>
        /// <param name="xml">The XML document text</param>
        /// <param name="parentPath">Path to the parent</param>
        public void Add(string xml, string parentPath)
        {
            try
            {
                XmlDocument document = new XmlDocument();
                try
                {
                    document.LoadXml(xml);
                }
                catch (XmlException)
                {
                    MainPresenter.ShowMessage("Invalid XML. Are you sure you're trying to paste an APSIM model?", Simulation.ErrorLevel.Error);
                }

                object newModel = XmlUtilities.Deserialise(document.DocumentElement, this.ApsimXFile.GetType().Assembly);

                // See if the presenter is happy with this model being added.
                Model         parentModel   = Apsim.Get(this.ApsimXFile, parentPath) as Model;
                AllowDropArgs allowDropArgs = new AllowDropArgs();
                allowDropArgs.NodePath   = parentPath;
                allowDropArgs.DragObject = new DragObject()
                {
                    NodePath  = null,
                    ModelType = newModel.GetType(),
                    Xml       = this.GetClipboardText()
                };

                this.OnAllowDrop(null, allowDropArgs);

                // If it is happy then issue an AddModelCommand.
                if (allowDropArgs.Allow)
                {
                    // If the model xml is a soil object then try and convert from old
                    // APSIM format to new.
                    if (document.DocumentElement.Name == "Soil" && XmlUtilities.Attribute(document.DocumentElement, "Name") != string.Empty)
                    {
                        XmlDocument newDoc = new XmlDocument();
                        newDoc.AppendChild(newDoc.CreateElement("D"));
                        APSIMImporter importer = new APSIMImporter();
                        importer.ImportSoil(document.DocumentElement, newDoc.DocumentElement, newDoc.DocumentElement);
                        XmlNode soilNode = XmlUtilities.FindByType(newDoc.DocumentElement, "Soil");
                        if (soilNode != null &&
                            XmlUtilities.FindByType(soilNode, "Sample") == null &&
                            XmlUtilities.FindByType(soilNode, "InitialWater") == null)
                        {
                            // Add in an initial water and initial conditions models.
                            XmlNode initialWater = soilNode.AppendChild(soilNode.OwnerDocument.CreateElement("InitialWater"));
                            XmlUtilities.SetValue(initialWater, "Name", "Initial water");
                            XmlUtilities.SetValue(initialWater, "PercentMethod", "FilledFromTop");
                            XmlUtilities.SetValue(initialWater, "FractionFull", "1");
                            XmlUtilities.SetValue(initialWater, "DepthWetSoil", "NaN");
                            XmlNode initialConditions = soilNode.AppendChild(soilNode.OwnerDocument.CreateElement("Sample"));
                            XmlUtilities.SetValue(initialConditions, "Name", "Initial conditions");
                            XmlUtilities.SetValue(initialConditions, "Thickness/double", "1800");
                            XmlUtilities.SetValue(initialConditions, "NO3/double", "10");
                            XmlUtilities.SetValue(initialConditions, "NH4/double", "1");
                            XmlUtilities.SetValue(initialConditions, "NO3Units", "kgha");
                            XmlUtilities.SetValue(initialConditions, "NH4Units", "kgha");
                            XmlUtilities.SetValue(initialConditions, "SWUnits", "Volumetric");
                        }

                        document.LoadXml(newDoc.DocumentElement.InnerXml);
                    }

                    IModel child = XmlUtilities.Deserialise(document.DocumentElement, this.ApsimXFile.GetType().Assembly) as IModel;

                    AddModelCommand command = new AddModelCommand(parentModel, document.DocumentElement, this.GetNodeDescription(child), this.view);
                    this.CommandHistory.Add(command, true);
                }
            }
            catch (Exception exception)
            {
                this.MainPresenter.ShowMessage(exception.Message, Simulation.ErrorLevel.Error);
            }
        }
Exemple #10
0
        /// <summary>
        /// Convert an XML parameter array into a series of commands.
        /// </summary>
        /// <param name="parentNode">The XML parameter node.</param>
        /// <param name="parameterName">The name of the XML child parameter.</param>
        /// <param name="animalParamName">The name of a GrazPlan parameter.</param>
        /// <param name="commands">The list of comamnds to add to.</param>
        /// <param name="numValuesInArray">The number of values that should be in the array.</param>
        private static void ConvertArrayToCommands(XmlNode parentNode, string parameterName,
                                                   string animalParamName, List <PropertyReplacement> commands,
                                                   int numValuesInArray)
        {
            var parameterNode = FindChildWithPrefix(parentNode, parameterName);

            if (parameterNode != null)
            {
                var  stringValue      = parameterNode.InnerText;
                bool hasMissingValues = stringValue.StartsWith(",") || stringValue.EndsWith(",") || stringValue.Contains(",,");
                if (hasMissingValues)
                {
                    var values = stringValue.Split(',');
                    for (int i = 0; i != values.Length; i++)
                    {
                        if (values[i] != string.Empty)
                        {
                            if (animalParamName == "IntakeLactC")
                            {
                                if (i == 0)
                                {
                                    commands.Add(new PropertyReplacement($"FDairyIntakePeak", values[i]));
                                }
                                else
                                {
                                    commands.Add(new PropertyReplacement($"{animalParamName}[{i + 1}]", values[i]));
                                }
                            }
                            else
                            {
                                commands.Add(new PropertyReplacement($"{animalParamName}[{i + 2}]", values[i]));  // 1 based array indexing before equals sign.
                            }
                        }
                    }
                }
                else
                {
                    // See if an index was specified as part of the parameter name.
                    var nodeName = XmlUtilities.Attribute(parameterNode, "name");
                    if (nodeName != parameterName)
                    {
                        // There must be an index specified e.g. c-w-0
                        var index = Convert.ToInt32(nodeName.Replace(parameterName, ""));
                        commands.Add(new PropertyReplacement($"{animalParamName}[{index + 1}]", stringValue));   // 1 based array indexing before equals sign.
                    }
                    else
                    {
                        // Determine if we need to add another value to the top of the values list
                        // so that the number of values matches the array length definition in the animprm.cs code.
                        var values = stringValue.Split(',');
                        if (values.Length != numValuesInArray)
                        {
                            // Add a zero to the top of the list of values.
                            var valuesList = new List <string>(values);
                            valuesList.Insert(0, "0");
                            values = valuesList.ToArray();
                        }
                        // We build the string value.
                        stringValue = StringUtilities.BuildString(values, ",");

                        // Create the command.
                        commands.Add(new PropertyReplacement(animalParamName, stringValue));
                    }
                }
            }
        }
Exemple #11
0
        /// <summary>Converts a .apsimx string to the latest version.</summary>
        /// <param name="st">XML or JSON string to convert.</param>
        /// <param name="toVersion">The optional version to convert to.</param>
        /// <param name="fileName">The optional filename where the string came from.</param>
        /// <returns>Returns true if something was changed.</returns>
        public static ConverterReturnType DoConvert(string st, int toVersion = -1, string fileName = null)
        {
            ConverterReturnType returnData = new ConverterReturnType();

            if (toVersion == -1)
            {
                toVersion = LatestVersion;
            }

            int  offset            = st.TakeWhile(c => char.IsWhiteSpace(c)).Count();
            char firstNonBlankChar = st[offset];

            if (firstNonBlankChar == '<')
            {
                bool        changed = XmlConverters.DoConvert(ref st, Math.Min(toVersion, XmlConverters.LastVersion), fileName);
                XmlDocument doc     = new XmlDocument();
                doc.LoadXml(st);
                int fileVersion = Convert.ToInt32(XmlUtilities.Attribute(doc.DocumentElement, "Version"), CultureInfo.InvariantCulture);
                if (fileVersion == toVersion)
                {
                    return new ConverterReturnType()
                           {
                               DidConvert = changed, RootXml = doc
                           }
                }
                ;

                st = ConvertToJSON(st, fileName);
                returnData.Root = JObject.Parse(st);
            }
            else if (firstNonBlankChar == '{')
            {
                // json
                returnData.Root = JObject.Parse(st);
            }
            else
            {
                throw new Exception("Unknown string encountered. Not JSON or XML. String: " + st);
            }

            if (returnData.Root.ContainsKey("Version"))
            {
                int fileVersion = (int)returnData.Root["Version"];

                if (fileVersion > LatestVersion)
                {
                    throw new Exception(string.Format("Unable to open file '{0}'. File version is greater than the latest file version. Has this file been opened in a more recent version of Apsim?", fileName));
                }

                // Run converters if not at the latest version.
                while (fileVersion < toVersion)
                {
                    returnData.DidConvert = true;

                    // Find the method to call to upgrade the file by one version.
                    int        versionFunction = fileVersion + 1;
                    MethodInfo method          = typeof(Converter).GetMethod("UpgradeToVersion" + versionFunction, BindingFlags.NonPublic | BindingFlags.Static);
                    if (method == null)
                    {
                        throw new Exception("Cannot find converter to go to version " + versionFunction);
                    }

                    // Found converter method so call it.
                    method.Invoke(null, new object[] { returnData.Root, fileName });

                    fileVersion++;
                }

                if (returnData.DidConvert)
                {
                    returnData.Root["Version"] = fileVersion;
                    st = returnData.Root.ToString();
                }
            }
            returnData.DidConvert = EnsureSoilHasInitWaterAndSample(returnData.Root) || returnData.DidConvert;

            return(returnData);
        }