// ---------------------------------------------------------------------------------------- /// <!-- _CreateNodes --> /// <summary> /// Inserts a fragment to fullfill nodes specified by an xpath /// </summary> /// <remarks> /// To insert a node based on an xpath I could... /// a. use the XML generator to build 'complete templates' (somewhat attractive option (see 'e' below)) /// b. create this as an implementation of the XML generator (much much too closely coupled) /// c. * iterate through the insert node locations until the xml validates (terribly ineficient but fairly simple) /// d. dig into the schema and do analysis (very very complicated) /// e. use the xpath as an input to the generator to make sure the required node is there (attractive option) /// f. just do it wrong (won't validate) /// g. make sure that xmls always have the needed nodes (don't control the xmls) /// h. suck out all the data and build a new xml with it (huge pretty big project, unreliable, very slow) - use approach h as the general approach to what I am doing /// i. keep track of positions in some array somewhere (too compolicated - like 'd') /// j. convert to a more explicit xpath (is there a more explicit xpath?) /// k. use LINQ (need to upgrade to vs 2008 - and learn LINQ) /// * I picked c /// /// Warning: /// Validity may require data /// </remarks> /// <param name="xdoc"></param> /// <returns></returns> public XmlNode _CreateNodes(PathSlicer xpath, string value) { string original = _doc.OuterXml; Validator val = new Validator(); XmlNode fragment; XmlNode sibling; XmlNode parent; int level; // ---------------------------------------------------------------------- // This won't work properly without a schema // ---------------------------------------------------------------------- if (_doc.Schemas == null || _doc.Schemas.Count == 0) { throw new XmlSchemaException("CreateNodes error -" + " document needs an included schema set" + " for PathBuilder.CreateNodes to work properly"); } // ---------------------------------------------------------------------- // It should blow up if it's not valid to start with // ---------------------------------------------------------------------- if (!val.IsValid(_doc)) { throw new XmlException("CreateNodes error -" + " xml document is not valid to start with" + " according to schema " + _SchemaSetName(_doc)); } // ---------------------------------------------------------------------- // It should blow up if the xpath root does nto match the xml root // ---------------------------------------------------------------------- level = this._BreakLevel(xpath, "ns0"); if (level == 0) { throw new Exception("CreateNodes error -" + " may not use an xpath to change an xml document" + " if the root nodes are not the same"); } // ---------------------------------------------------------------------- // Insert a fragment to complete the xpath // 1. Get level in xpaths telescope at which node does not exist // 2. Create a fragment to match the missing xpath // 3. Identify where to insert it (parent) // 4. Insert it as the first child // ---------------------------------------------------------------------- fragment = _CreateNodes(xpath, level, value); if (level > 0) { parent = _GetNode("ns0", xpath.SubPaths[level - 1]); parent.InsertBefore(fragment, parent.FirstChild); // ------------------------------------------------------------------ // Move the new fragment along until the document validates // ------------------------------------------------------------------ sibling = fragment.NextSibling; while (sibling != null && !val.IsValid(_doc)) { sibling = fragment.NextSibling; parent.RemoveChild(fragment); parent.InsertAfter(fragment, sibling); } } else { parent = null; } // ---------------------------------------------------------------------- // Restore original document if it didn't work // ---------------------------------------------------------------------- if (!val.IsValid(_doc)) { _doc.LoadXml(original); } return(_GetNode("ns0", xpath.Path)); }
// ---------------------------------------------------------------------------------------- /// <!-- _RecordImport --> /// <summary> /// Adds an import file to the _imports dictionary /// </summary> /// <param name="nameSpace"></param> /// <param name="fileName"></param> public void _RecordImport(string nameSpace, string fileName) { _imports[nameSpace] = new PathSlicer(fileName, "."); }
// ---------------------------------------------------------------------------------------- // Custom Methods // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- /// <!-- _Bool --> /// <summary> /// /// </summary> /// <param name="xdoc"></param> /// <param name="namespacePrefix"></param> /// <param name="defaultValue"></param> /// <returns></returns> public bool _Bool(PathSlicer xpath, string namespacePrefix, bool defaultValue) { return(TreatAs.BoolValue(_Str(xpath, namespacePrefix, ""), defaultValue)); }
// ---------------------------------------------------------------------------------------- /// <!-- _Load_simple --> /// <summary> /// A load that tries a few places to load an xml schema from /// </summary> /// <param name="newXml"></param> /// <param name="schemaLocation"></param> /// <returns></returns> public string _Load_simple(string schemaLocation, string hint1, string hint2, string hint3) { if (Regex.IsMatch(schemaLocation, ":")) { throw new FormatException("There should not be a : in the path " + schemaLocation); } string whereFound = ""; PathSet paths = new PathSet(); string tryHere = PathSlicer.FindPath(schemaLocation, hint1, hint2); try { whereFound = _Load(_baseLocation, schemaLocation); SetBaseLocation = whereFound; } catch { try { whereFound = _Load(tryHere); SetBaseLocation = whereFound; } catch { try { whereFound = _Load("", schemaLocation); SetBaseLocation = whereFound; } catch { } } } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, ""); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint1); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint1 + "\\" + hint2); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint2); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint2 + "\\" + hint1); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint1 + "\\" + hint2 + "\\" + hint3); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint2 + "\\" + hint3); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint3); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint1 + "\\" + hint3); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint3 + "\\" + hint1); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint3 + "\\" + hint2); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint1 + "\\" + hint3 + "\\" + hint2); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint2 + "\\" + hint1 + "\\" + hint3); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint2 + "\\" + hint3 + "\\" + hint1); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint3 + "\\" + hint1 + "\\" + hint2); } if (string.IsNullOrEmpty(whereFound)) { whereFound = TryLoad(schemaLocation, hint3 + "\\" + hint2 + "\\" + hint1); } return(whereFound); }