//============================================================================== /// <summary> /// Edits the <initdata> and replaces the consts/param values with [model] macro /// </summary> /// <param name="initText">The initdata section XML</param> /// <returns>The initdata section with only the inits and comments</returns> //============================================================================== public String RemoveConsts(String initText) { String result = initText; int i; XmlNode anode; TXMLParser parser; Boolean found; XmlNode nextNode; if (!initText.Contains(MODELMACRO)) //if the [model] macro is not in the inittext then { if (InitNames.Count > 0) { parser = new TXMLParser(initText); anode = parser.firstChild(parser.rootNode()); // for each (init) node in the xml while (anode != null) //get the nodename { if (parser.getNodeType(anode) == XmlNodeType.Element) { i = 0; found = false; while (!found && (i <= InitNames.Count - 1)) { if (anode.Name == InitNames[i]) { found = true; //terminate loop } i++; } if (!found) //if the node name is not found in the init list then { nextNode = parser.nextSibling(anode); parser.rootNode().RemoveChild(anode); //delete the node anode = nextNode; } else { anode = parser.nextSibling(anode); // for each node in the xml } } else { anode = parser.nextSibling(anode); // for each node in the xml } } result = "<initdata>" + CR + parser.rootNode().InnerXml + CR + " " + MODELMACRO + CR + " </initdata>"; } } return(result); }
//============================================================================== /// <summary> /// Get the context string from the specified context file. This could be a .ctx /// file or an apsim .xml file. /// </summary> /// <param name="strContext"></param> /// <param name="modelConsts"></param> /// <param name="dllPath"></param> /// <param name="expandModel">Expand the Model macro in an APSIM init section</param> //============================================================================== public void getContextFromFile(out String strContext, out String modelConsts, String dllPath, Boolean expandModel) { StreamReader fileStream; String context; TXMLParser xmlParse; XmlNode anode; XmlNode metaDataNode; XmlNode modelNode; XmlNode compNode; XmlNode childNode; String compName; String compDll = ""; string compClass = ""; String model; StringBuilder buf; String xml; int i; List <String> dllList; String nodeName; model = ""; strContext = ""; fileStream = new StreamReader(FContextFile); context = fileStream.ReadToEnd(); if (Path.GetExtension(FContextFile).ToLower() == ".ctx") { strContext = context; XmlDocument doc = new XmlDocument(); doc.LoadXml(strContext); String exe = doc.DocumentElement.GetAttribute("executable"); if ((exe.Length > 0) && !exe.Contains(Path.DirectorySeparatorChar.ToString()) && dllPath.Contains(Path.DirectorySeparatorChar.ToString())) { XmlNode exeAttr = doc.DocumentElement.GetAttributeNode("executable"); if (exeAttr != null) { exeAttr.Value = dllPath; strContext = doc.OuterXml; } } } else //an apsim .xml file { dllList = new List <String>(); xmlParse = new TXMLParser(context); metaDataNode = xmlParse.firstElementChild(xmlParse.rootNode(), "MetaData"); if (metaDataNode != null) { modelNode = null; getDllList(xmlParse, metaDataNode, dllList); anode = xmlParse.firstElementChild(metaDataNode, "ApsimToSim"); if (anode != null) { if (dllList.Count < 1) { throw new Exception("No dll's found in the context file."); } compNode = FindCompNode(xmlParse, anode, dllList[0], dllPath); //find the matching component section for dllPath if (compNode != null) { compDll = dllPath; //we know the full path so use it compClass = xmlParse.getAttrValue(compNode, "class"); FInitList.Clear(); //now expand the sections under <component><initdata> anode = xmlParse.firstElementChild(compNode, "initdata"); if (anode != null) { anode = xmlParse.firstChild(anode); while (anode != null) //while more children under <initdata> { nodeName = anode.Name; if (nodeName == "PerformInstructions") { childNode = xmlParse.firstElementChild(anode, "ConstructModel"); if (childNode != null) { model = StripMacros(xmlParse.InnerXml(childNode)); break; } } xml = anode.OuterXml; if (xml.Length > 0) { if (xml.Contains("[Model")) //if this is a [Model] macro { if (expandModel) { modelNode = getModelNode(xmlParse, xml); //search for the matching <model> section model = xmlParse.InnerXml(modelNode); } else { model = " " + MODELMACRO + CR; } } if (xmlParse.getNodeType(anode) == XmlNodeType.Element) //get all the init names { FInitList.Add(nodeName); } } anode = xmlParse.nextSibling(anode); } } } //endif compNode <> nil } compName = findCompClassName(xmlParse, modelNode, compDll); if (compName == "") { compName = Path.GetFileNameWithoutExtension(compDll); } if (compClass == "") { compClass = Path.GetFileNameWithoutExtension(compDll); } buf = new StringBuilder(); //now build the correct xml for the context file buf.Append("<component name=\"" + compName.Trim() + "\" executable=\"" + compDll + "\"" + " class=\"" + compClass + "\">"); buf.Append(" <initdata>\r\n"); buf.Append(model); if (compClass.ToLower().StartsWith("plant.")) { if (InitNames.IndexOf("uptake_source") < 0) { InitNames.Add("uptake_source"); //ensure it is an init } } for (i = 0; i < FInitList.Count - 1; i++) { if (FInitList[i] == "uptake_source") { buf.Append(" <" + FInitList[i] + ">apsim</" + FInitList[i] + ">\r\n"); } else { buf.Append(" <" + FInitList[i] + "></" + FInitList[i] + ">\r\n"); } } buf.Append(" </initdata>"); buf.Append("</component>"); strContext = buf.ToString(); } } modelConsts = model; }