public static GetManditoryAttributeValue ( |
||
node | The XmlNode to look in. | |
attrName | string | The required attribute to find. |
return | string |
private string GetTxtAtributeValue(XmlNode node) { return(XmlUtils.GetOptionalAttributeValue( node, "txt", XmlUtils.GetManditoryAttributeValue(node, "id"))); // 'id' is default, if no 'txt' attribute is present. }
private static object[] CreateArgs(XmlNode configuration) { List <object> argList = new List <object>(); // see if we can find "args" children that specify arguments to pass in. if (configuration != null && configuration.HasChildNodes) { XmlNodeList argNodes = configuration.SelectNodes("args/arg"); if (argNodes.Count > 0) { Dictionary <string, string> argDict = new Dictionary <string, string>(); foreach (XmlNode argNode in argNodes) { string argName = XmlUtils.GetManditoryAttributeValue(argNode, "name"); string argVal = XmlUtils.GetManditoryAttributeValue(argNode, "value"); argDict.Add(argName, argVal); } string argValue; if (argDict.TryGetValue("xpathToConfigurationNode", out argValue)) { // "xpathToConfigurationNode" is a special argument for passing the nodes // that the object we're creating knows how to process. // NOTE: assume the xpath is with respect to the dynamicloaderinfo "configuration" node XmlNode configNodeForObject = configuration.SelectSingleNode(argValue); if (configNodeForObject != null) { argList.Add(configNodeForObject); } } } } return(argList.Count > 0 ? argList.ToArray() : null); }
/// <summary> /// replace every <include/> node in the document with the nodes that it references /// </summary> /// <param name="cachedDoms"></param>= /// <param name="parentPath"></param>= /// <param name="dom"></param>= protected void ProcessDom(Dictionary <string, XmlDocument> cachedDoms, string parentPath, XmlDocument dom) { XmlNode nodeForError = null; string baseFile = ""; XmlNode baseNode = dom.SelectSingleNode("//includeBase"); if (baseNode != null) { baseFile = XmlUtils.GetManditoryAttributeValue(baseNode, "path"); //now that we have read it, remove it, so that it does not violate the schema of //the output file. baseNode.ParentNode.RemoveChild(baseNode); } try { foreach (XmlNode includeNode in dom.SelectNodes("//include")) { nodeForError = includeNode; ReplaceNode(cachedDoms, parentPath, includeNode, baseFile); } } catch (Exception error) { throw new ApplicationException("Error while processing <include> element:" + nodeForError.OuterXml, error); } Debug.Assert(dom.SelectSingleNode("//include") == null, "some <include> node was not handled"); }
/// <summary> /// replace the node with the node or nodes that it refers to /// </summary> /// <example> /// <include path='IncludeXmlTestSource.xml' query='food/fruit/name'/> /// </example> /// <param name="targetNode"></param> protected void CopyElement(XmlDocument dom, XmlNode copyInstructionNode) { string id = XmlUtils.GetManditoryAttributeValue(copyInstructionNode, "idref"); XmlNode node = copyInstructionNode.OwnerDocument.SelectSingleNode("//*[@id='" + id + "']"); if (node == null) { throw new ApplicationException("Could not find an element in this file with the id of '" + id + "', in order to do the <copyElement> ."); } copyInstructionNode.ParentNode.ReplaceChild(node.CloneNode(true), copyInstructionNode); }
/// <summary> /// Dynamically find an assembly and create an object of the name to class. /// configuration has assemblyPath and class (fully qualified) as in other overloads. /// The constructor arguments are supplied explicitly. /// </summary> /// <returns></returns> static public Object CreateObject(XmlNode configuration, params object[] args) { string assemblyPath = XmlUtils.GetManditoryAttributeValue(configuration, "assemblyPath"); // JohnT: see AddAssemblyPathInfo. We use this when the object we're trying to persist // as a child of another object is null. if (assemblyPath == "null") { return(null); } string className = XmlUtils.GetManditoryAttributeValue(configuration, "class"); return(CreateObject(assemblyPath, className, args)); }
private void MergeCustomGroups(XmlNode parentNode, XmlNodeList customGroupNodeList) { if (customGroupNodeList == null || customGroupNodeList.Count == 0) { return; // Stop recursing in this method. } foreach (XmlNode customGroupNode in customGroupNodeList) { string customGroupId = XmlUtils.GetManditoryAttributeValue(customGroupNode, "id"); XmlNode srcMatchingGroupNode = parentNode.SelectSingleNode("group[@id='" + customGroupId + "']"); if (srcMatchingGroupNode == null) { // Import the entire custom node. m_document.DocumentElement.AppendChild(m_document.ImportNode(customGroupNode, true)); } else { // 1. Import new strings, or override extant strings with custom strings. foreach (XmlNode customStringNode in customGroupNode.SelectNodes("string")) { string customId = XmlUtils.GetManditoryAttributeValue(customStringNode, "id"); string customTxt = GetTxtAtributeValue(customStringNode); XmlNode srcMatchingStringNode = srcMatchingGroupNode.SelectSingleNode("string[@id='" + customId + "']"); if (srcMatchingStringNode == null) { // Import the new string into the extant group. srcMatchingGroupNode.AppendChild(m_document.ImportNode(customStringNode, true)); } else { // Replace the original value with the new value. // The 'txt' attribute is optional, but it will be added as a cpoy of the 'id' here, if needed. string srcTxt = XmlUtils.GetOptionalAttributeValue(srcMatchingStringNode, "txt"); if (srcTxt == null) { XmlUtils.AppendAttribute(srcMatchingStringNode, "txt", customTxt); } else { srcMatchingStringNode.Attributes["txt"].Value = customTxt; } } } // 2. Group elements can be nested, so merge them, too. MergeCustomGroups(srcMatchingGroupNode, customGroupNode.SelectNodes("group")); } } }
// Return the class of object that will be created if CreateObjectUsingLoaderNode is called with this argument. // Return null if dynamic loader node not found or if it doesn't specify a valid class. static public Type TypeForLoaderNode(XmlNode parentConfigNode) { XmlNode configuration = parentConfigNode.SelectSingleNode("dynamicloaderinfo"); if (configuration == null) { return(null); } string assemblyPath = XmlUtils.GetManditoryAttributeValue(configuration, "assemblyPath"); if (assemblyPath == "null") { return(null); } string className = XmlUtils.GetManditoryAttributeValue(configuration, "class"); Assembly assembly; GetAssembly(assemblyPath, out assembly); return(assembly.GetType(className.Trim())); }
/// <summary> /// look up a list of string IDs and return an array of strings /// </summary> /// <example> /// here, the strings will be looked up at the root level /// <stringList ids="anywhere, somewhere to left, somewhere to right, adjacent to left, adjacent to right"/> /// </example> /// <example> /// here, the strings will be looked up under a nested group /// <stringList group="MoMorphAdhocProhib/adjacency" ids="anywhere, somewhere to left, somewhere to right, adjacent to left, adjacent to right"/> /// </example> /// <param name="node">the name of the node is ignored, only the attributes are read</param> /// <returns></returns> public string[] GetStringsFromStringListNode(XmlNode node) { string ids = XmlUtils.GetManditoryAttributeValue(node, "ids"); string[] idList = ids.Split(new char[] { ',' }); string[] strings = new string[idList.Length]; string groupPath = ""; string simplePath = XmlUtils.GetOptionalAttributeValue(node, "group"); if (simplePath != null) { groupPath = GetXPathFragmentFromSimpleNotation(simplePath); } int i = 0; foreach (string id in idList) { strings[i++] = GetStringWithXPath(id, groupPath); } return(strings); }
/// <summary> /// replace the node with the node or nodes that it refers to /// </summary> /// <example> /// <include path='IncludeXmlTestSource.xml' query='food/fruit/name'/> /// </example> /// <param name="includeNode"></param> protected void ReplaceNode(Dictionary <string, XmlDocument> cachedDoms, string parentPath, XmlNode includeNode, string defaultPath) { string path = null; if (defaultPath != null && defaultPath.Length > 0) { path = XmlUtils.GetOptionalAttributeValue(includeNode, "path", defaultPath); } else { path = XmlUtils.GetOptionalAttributeValue(includeNode, "path"); if (path == null || path.Trim().Length == 0) { throw new ApplicationException( "The path attribute was missing and no default path was specified. \r\n" + includeNode.OuterXml); } } XmlNode parentNode = includeNode.ParentNode; try { /* To support extensions, we need to see if 'path' starts with 'Extensions/* /'. (without the extra space following the '*'.) * If it does, then we will have to get any folders (the '*' wildcard) * and see if any of them have the specified file (at end of 'path'. */ StringCollection paths = new StringCollection(); // The extension XML files should be stored in the data area, not in the code area. // This reduces the need for users to have administrative privileges. bool fExtension = false; string extensionBaseDir = null; if (path.StartsWith("Extensions") || path.StartsWith("extensions")) { // Extension <include> element, // which may have zero or more actual extensions. string extensionFileName = path.Substring(path.LastIndexOf("/") + 1); string pluginBaseDir = (parentPath == null) ? m_resolver.BaseDirectory : parentPath; extensionBaseDir = pluginBaseDir; string sBaseCode = DirectoryFinder.FWCodeDirectory; string sBaseData = DirectoryFinder.FWDataDirectory; if (extensionBaseDir.StartsWith(sBaseCode) && sBaseCode != sBaseData) { extensionBaseDir = extensionBaseDir.Replace(sBaseCode, sBaseData); } // JohnT: allow the Extensions directory not even to exist. Just means no extentions, as if empty. if (!Directory.Exists(extensionBaseDir + "/Extensions")) { return; } foreach (string extensionDir in Directory.GetDirectories(extensionBaseDir + "/Extensions")) { string extensionPathname = Path.Combine(extensionDir, extensionFileName); // Add to 'paths' collection, but only from 'Extensions' on. if (File.Exists(extensionPathname)) { paths.Add(extensionPathname.Substring(extensionPathname.IndexOf("Extensions"))); } } // Check for newer versions of the extension files in the // "Available Plugins" directory. See LT-8051. UpdateExtensionFilesIfNeeded(paths, pluginBaseDir, extensionBaseDir); if (paths.Count == 0) { return; } fExtension = true; } else { // Standard, non-extension, <include> element. paths.Add(path); } /* Any fragments (extensions or standard) will be added before the <include> * element. Aftwerwards, the <include> element will be removed. */ string query = XmlUtils.GetManditoryAttributeValue(includeNode, "query"); foreach (string innerPath in paths) { XmlDocumentFragment fragment; if (innerPath == "$this") { fragment = CreateFragmentWithTargetNodes(query, includeNode.OwnerDocument); } else { fragment = GetTargetNodes(cachedDoms, fExtension ? extensionBaseDir : parentPath, innerPath, query); } if (fragment != null) { XmlNode node = includeNode.OwnerDocument.ImportNode(fragment, true); // Since we can't tell the index of includeNode, // always add the fluffed-up node before the include node to keep it/them in the original order. parentNode.InsertBefore(node, includeNode); } } // Handle any overrides. HandleIncludeOverrides(includeNode); } finally { // Don't want the original <include> element any more, no matter what. parentNode.RemoveChild(includeNode); } }