/// <summary> /// Create new reference /// </summary> /// <param name="name"></param> /// <returns></returns> public VXmlReference CreateReference(VXmlNode n) { if (!DEFX.BR_NODE_REFERENCE(n.NodeTypeCode)) { throw new VXmlException(VXmlException.E0004_INVALID_NODE_TYPE_CODE, ": " + n.NodeType + " (Create Reference)"); } // Check if this object is already in child node or reference VXmlNodeCollection refs = this.get_child_nodes_of_type(DEFX.NODE_TYPE_REFERENCE); //Check if ref already exists foreach (VXmlReference rf in refs) { if (rf.ReferenceId == n.Id) { return(rf); } } VXmlReference r = (VXmlReference)create_node(DEFX.NODE_TYPE_REFERENCE, n.Name); r.set_reference_node(n); root_catalog.index_reference.Insert(n.ID, r.Id); // Add index return(r); }
/// <summary> /// Parse from string /// </summary> /// <param name="xmlstring"></param> public static VXMLTemplate Parse(string xp, string name) { VXMLTemplate t = new VXMLTemplate(name); VXMLTemplate stack = new VXMLTemplate("stack"); List <int> pages = new List <int>(1024); stack.Add(DEF_DUMMY, DEFX.NODE_TYPE_UNDEFINED); // Add 1st (dummy) recor to the stack pages.Add(0); int sf = 0; while (sf < (xp.Length - 3)) { if (xp.Substring(sf, DEFS.DELIM_NEWLINE.Length) == DEFS.DELIM_NEWLINE) { sf += 2; pages.Add(sf); } else { sf++; } } string error = ""; int pos = 0; if (xp.Length == 0) { return(t); } string s = ""; string ns = ""; string x = xp + " "; while ((pos < x.Length) & (error == "")) { /////////////////////////// Node tag /////////////////////////// if (x.Substring(pos, 1) == "<") { pos++; // <!-- if (x.Substring(pos, CONTEXT_COMMENT_START.Length) == CONTEXT_COMMENT_START) { pos += CONTEXT_COMMENT_START.Length; ns = get_value(ref x, pos, CONTEXT_COMMENT_END); if (ns != DEF_ERROR) { t.Add(DEF_COMMENT, DEFX.NODE_TYPE_COMMENT, DEFX.GET_NODETYPE(DEFX.NODE_TYPE_COMMENT), ns.Trim()); pos += ns.Length + CONTEXT_COMMENT_END.Length; ns = ""; } else { error = "Missing/invalid comment closing tag" + get_pos(ref pages, ref pos); } } // <? else if (x.Substring(pos, CONTEXT_INSTRUCTION_START.Length) == CONTEXT_INSTRUCTION_START) { pos += CONTEXT_INSTRUCTION_START.Length; ns = get_value(ref x, pos, CONTEXT_INSTRUCTION_END); if (ns != DEF_ERROR) { t.Add(DEF_INSTRUCTION, DEFX.NODE_TYPE_INSTRUCTION, DEFX.GET_NODETYPE(DEFX.NODE_TYPE_INSTRUCTION), ns.Trim()); pos += ns.Length + CONTEXT_INSTRUCTION_END.Length; ns = ""; } else { error = "Missing/invalid instruction closing tag" + get_pos(ref pages, ref pos); } } // '</' - closing node tag else if (x.Substring(pos, CONTEXT_NODE_END_LONG.Length) == CONTEXT_NODE_END_LONG) { pos += CONTEXT_NODE_END_LONG.Length; int i = x.IndexOf(CONTEXT_NODE_END, pos); // Find '>' if (i <= pos) { error = "Missing/invalid node closing tag" + get_pos(ref pages, ref pos); } else { string n_name = x.Substring(pos, i - pos); string val = s; s = ""; if (stack[stack.Count - 1].name == n_name) { // Set value while (val.Length > 0) { string ch = val.Substring(0, 1); if ((ch == " ") | (ch == "\t") | (ch == "\r") | (ch == "\n")) { val = val.Remove(0, 1); } else { break; } } while (val.Length > 0) { string ch = val.Substring(val.Length - 1, 1); if ((ch == " ") | (ch == "\t") | (ch == "\r") | (ch == "\n")) { val = val.Remove(val.Length - 1, 1); } else { break; } } t.Add(DEF_END, stack[stack.Count - 1].type, n_name); // Add End node VXMLINT vi = t[stack[stack.Count - 1].index]; vi.value = val; t.RemoveAt(stack[stack.Count - 1].index); t.Insert(stack[stack.Count - 1].index, vi); stack.RemoveAt(stack.Count - 1); // Remove node from stack pos = i + 1; } else { error = "Closing tag name doesnt match" + get_pos(ref pages, ref pos); } } } // < else { string st_name = get_name(ref x, ref pos, ">", "/>", " "); if (st_name.Length == 0) { error = "Missing node name" + get_pos(ref pages, ref pos); } else { short node_type = DEFX.NODE_TYPE_ELEMENT; if (st_name == DEFX.GET_NODETYPE(DEFX.NODE_TYPE_TEXT)) { node_type = DEFX.NODE_TYPE_TEXT; } else if (st_name == DEFX.GET_NODETYPE(DEFX.NODE_TYPE_COMMENT)) { node_type = DEFX.NODE_TYPE_COMMENT; } else if (st_name == DEFX.GET_NODETYPE(DEFX.NODE_TYPE_CONTENT)) { node_type = DEFX.NODE_TYPE_CONTENT; } t.Add(DEF_START, node_type, st_name); stack.Add(DEF_START, node_type, st_name, "", (t.Count - 1)); // Handle attributes bool eon = false; while ((pos < x.Length) & (error == "")) { if ((x.Substring(pos, 1) == " ") | (x.Substring(pos, 1) == "\t")) { pos++; } else if (x.Substring(pos, 2) == DEFS.DELIM_NEWLINE) { pos += 2; } // '>' else if (x.Substring(pos, CONTEXT_NODE_END.Length) == CONTEXT_NODE_END) { pos++; eon = true; break; } // '/>' else if (x.Substring(pos, CONTEXT_NODE_END_SHORT.Length) == CONTEXT_NODE_END_SHORT) { pos += 2; eon = true; t.Add(DEF_END, node_type, st_name); stack.RemoveAt(stack.Count - 1); // Remove node from stack break; } // Process attribute else { string a_name = get_name(ref x, ref pos, "="); if (name.Length == 0) { error = "Missing attribute name" + get_pos(ref pages, ref pos); } else { if (x.Substring(pos, 2) != @"=""") { error = "Error in attribute definition" + get_pos(ref pages, ref pos); } else { pos += 2; int i = x.IndexOf(@"""", pos); if (i < 0) { error = @"Missing closing '""' in attribute definition" + get_pos(ref pages, ref pos); } else { string v = (i == pos) ? "" : x.Substring(pos, i - pos); pos = i + 1; t.Add(DEF_ATTRIBUTE, DEFX.NODE_TYPE_ATTRIBUTE, a_name, v); } } } } } if ((error == "") & (!eon)) { error = "Missing closing '>'" + get_pos(ref pages, ref pos); } } } } /////////////////////////// Node value /////////////////////////// else { if (stack.Count == 1) // NOT node value { if ((x.Substring(pos, 1) == " ") | (x.Substring(pos, 1) == "\t")) { pos++; } else if (x.Substring(pos, 2) == DEFS.DELIM_NEWLINE) { pos += 2; } else { error = "Unrecognized term" + get_pos(ref pages, ref pos); } } else if (stack[stack.Count - 1].def == DEF_START) { string s1 = get_value(ref x, pos, CONTEXT_NODE_START); s += s1; if (s == DEF_ERROR) { error = "Missing/invalid node closing tag" + get_pos(ref pages, ref pos); } else { pos += s1.Length; } } else { error = "Unrecognized term" + get_pos(ref pages, ref pos); } } } // Post-processing if (error != "") { t.Clear(); t.Add(DEF_ERROR, 0, "Parse error", error); } else if (stack.Count > 1) { t.Clear(); t.Add(DEF_ERROR, 0, "Parse error", "No closing tag" + get_pos(ref pages, ref pos)); } return(t); }
/// <summary> /// Load child node from xml string /// </summary> /// <param name="xmlstring">XML string to load</param> /// <param name="name">Node name to create</param> /// <param name="fileref">Reference to file</param> /// <param name="parent">Parent VXML node</param> /// <returns></returns> private string load_xml_data(string xmlstring, string name, string xml_fileref, VXmlNode parent) { if (parent == null) { if (this.DocumentElement != null) { this.DocumentElement.Remove(); } } VXmlNode n = (parent == null) ? this : parent; if (!DEFX.BR_XML_IS_VALID_TYPE(n.NodeTypeCode)) { return(VXmlException.GetMessage(VXmlException.E0004_INVALID_NODE_TYPE_CODE) + ": " + n.NodeType); } VXMLTemplate t = null; if (template_cache == null) { template_cache = new List <VXMLTemplate>(32); } for (int i = 0; i < template_cache.Count; i++) { if (template_cache[i].template_name == name) { t = template_cache[i]; } } if (t == null) // Not found in cache { t = VXmlParser.Parse(xmlstring, name); if (t.Count == 1) { if (t[0].def == VXmlParser.DEF_ERROR) { return(VXmlException.GetMessage(VXmlException.E0020_XML_PARSE_ERROR_CODE) + ": " + t[0].value); // Return error } } } if (t.Count == 0) { return(""); } int j = 0; List <VXmlNode> stack = new List <VXmlNode>(); stack.Add(n); while (j < t.Count) { int stack_n = stack.Count - 1; if (t[j].def == VXmlParser.DEF_INSTRUCTION) { // Just ignore } else if (t[j].def == VXmlParser.DEF_COMMENT) { stack[stack_n].CreateComment(t[j].value); } else if (t[j].def == VXmlParser.DEF_ATTRIBUTE) { stack[stack_n].SetAttribute(t[j].name, t[j].value); } else if (t[j].def == VXmlParser.DEF_START) { if (t[j].type == DEFX.NODE_TYPE_TEXT) { stack[stack_n].CreateTextNode(t[j].value); } else { VXmlNode new_node = null; switch (t[j].type) { case DEFX.NODE_TYPE_CONTENT: new_node = stack[stack_n].CreateContent(""); break; case DEFX.NODE_TYPE_ELEMENT: new_node = stack[stack_n].CreateElement(t[j].name, t[j].value); break; default: break; } stack.Add(new_node); } } else if (t[j].def == VXmlParser.DEF_END) { if (stack[stack_n].NodeTypeCode == DEFX.NODE_TYPE_CONTENT) { VXmlContent c = ((VXmlContent)stack[stack_n]); if (c.fileref != "") { string xp = Path.GetDirectoryName(xml_fileref); string cp = Path.GetDirectoryName(c.fileref); if (cp == "") { cp = xp; // If path is not specified in the 'fileref' - use xml file path } string nm = Path.GetFileName(c.fileref); if (cp != "") { nm = cp + @"\" + nm; } if (File.Exists(nm)) { c.Upload(nm, true); c.fileref = nm; } else { return("Content file '" + nm + " is not found"); } } } if (t[j].type != DEFX.NODE_TYPE_TEXT) { stack.RemoveAt(stack_n); } } else { throw new VXmlException(VXmlException.E0020_XML_PARSE_ERROR_CODE, "- invalid parsed sequence: " + t[j].def); } j++; } return(""); }