private void LoadNodeList(XmlNodeList nodeList, int version, XmlNode root) { foreach(XmlNode node in nodeList) { // Load only nodes that either have matching version number or none. // JohnT says that all user files will have a version number, and have had one from the beginning. // None of our installer provided files have a version number. // That is why we check for an optional version attribute. int fileVersion = Int32.Parse(XmlUtils.GetOptionalAttributeValue(node, "version", version.ToString())); if (fileVersion != version && Merger != null && XmlUtils.GetOptionalAttributeValue(node, "base") == null) { string[] keyAttrs; GetElementKey key = GetKeyMain(node, out keyAttrs); XmlNode current; if (m_getElementTable.TryGetValue(key, out current)) { XmlNode merged = Merger.Merge(current, node, m_mainDoc); NoteIfNodeWsTagged(merged); InsertNodeInDoc(merged, current, m_mainDoc, key); } else { // May be part of a named view or a duplicated node. Look for the unmodified one to merge with. if (keyAttrs.Length > 2 && keyAttrs[2] == "name" && key.KeyVals.Length > 2) { var copyName = key.KeyVals[2]; int index = copyName.IndexOfAny(new [] {kcMarkLayoutCopy, kcMarkNodeCopy}); if (index > 0) { var originalName = copyName.Substring(0, index); var originalKeyVals = (string[])key.KeyVals.Clone(); originalKeyVals[2] = originalName; var originalKey = new GetElementKey(key.ElementName, originalKeyVals, m_mainDoc); if (m_getElementTable.TryGetValue(originalKey, out current)) { XmlNode merged = Merger.Merge(current, node, m_mainDoc); XmlUtils.SetAttribute(merged, "name", copyName); // give it the name fro NoteIfNodeWsTagged(merged); // We do NOT want this one to replace 'current', since it has a different name. // We already know there is no matching node to replace. InsertNodeInDoc(merged, null, m_mainDoc, key); } } } } } else if (fileVersion == version) { NoteIfNodeWsTagged(node); AddNode(node, root); } // Otherwise it's an old-version node and we can't merge it, so ignore it. } }
private void InsertNodeInDoc(XmlNode newNode, XmlNode extantNode, XmlDocument doc, GetElementKey key) { XmlNode root = doc["Main"]; if (extantNode == null) root.AppendChild(newNode); else root.ReplaceChild(newNode, extantNode); if (newNode.Name != "layoutType") m_getElementTable[key] = newNode; }
private void CopyNodeToDoc(XmlNode node, XmlNode extantNode, XmlDocument doc, GetElementKey key) { XmlNode newNode = doc.ImportNode(node, true); InsertNodeInDoc(newNode, extantNode, doc, key); }
/// <summary> /// Compute and save in m_mainDoc a node which represents the actual meaning of the given /// alteration node, which has the specified element name and keys. /// </summary> /// <param name="alteration"></param> /// <returns></returns> private XmlNode ApplyAlteration(string elementName, string[] attrvals, XmlNode alteration) { string baseName = XmlUtils.GetManditoryAttributeValue(alteration, "base"); string[] baseKey = (string[])attrvals.Clone(); int cKeys = baseKey.Length; baseKey[cKeys - 1] = baseName; XmlNode baseNode = GetEltFromDoc(elementName, baseKey, m_mainDoc); XmlNode result = Unify(alteration, baseNode); m_mainDoc["Main"].AppendChild(result); // we may already have a 'miss' for this element cached, so update the table // 'result' may be null; GetElementKey key = new GetElementKey(elementName, attrvals, m_mainDoc); m_getElementTable[key] = result; return result; }
private void AddNode(XmlNode node, XmlNode root) { string[] keyAttrs; GetElementKey keyMain = GetKeyMain(node, out keyAttrs); string[] keyVals = keyMain.KeyVals; string elementName = keyMain.ElementName; XmlNode extantNode = null; // Value may be null in the Dictionary, even if key is present. m_getElementTable.TryGetValue(keyMain, out extantNode); // Is the current node a derived node? string baseName = XmlUtils.GetOptionalAttributeValue(node, "base"); if (baseName != null) { string id = XmlUtils.GetManditoryAttributeValue(node, keyAttrs[keyAttrs.Length - 1]); if (id == baseName) { // it is an override. if (extantNode == null) { // Possibly trying to override a derived element? extantNode = GetElement(elementName, keyVals); if (extantNode == null) throw new Exception("no base found to override " + baseName); } GetElementKey keyBase = new GetElementKey(elementName, keyVals, m_baseDoc); if (m_getElementTable.ContainsKey(keyBase)) throw new Exception("only one level of override is allowed " + baseName); // Save the base node for future use. m_baseDoc["Main"].AppendChild(m_baseDoc.ImportNode(extantNode, true)); m_getElementTable[keyBase] = extantNode; // Immediately compute the effect of the override and save it, replacing the base. XmlNode unified = Unify(node, extantNode); root.ReplaceChild(unified, extantNode); // and update the cache, which is loaded with the old element m_getElementTable[keyMain] = unified; } else { // it is a normal alteration node if (extantNode != null) { // derived node displaces non-derived one. root.RemoveChild(extantNode); } } // alteration node goes into alterations doc (displacing any previous alteration // with the same key). GetElementKey keyAlterations = new GetElementKey(elementName, keyVals, m_alterationsDoc); extantNode = null; if (m_getElementTable.ContainsKey(keyAlterations)) extantNode = m_getElementTable[keyAlterations]; // May still be null. CopyNodeToDoc(node, extantNode, m_alterationsDoc, keyAlterations); } else // not an override, just save it, replacing existing node if needed { CopyNodeToDoc(node, extantNode, m_mainDoc, keyMain); } }
protected XmlNode GetEltFromDoc(string elementName, string[] attrvals, XmlDocument doc) { GetElementKey key = new GetElementKey(elementName, attrvals, doc); XmlNode result = null; bool hasKey = m_getElementTable.ContainsKey(key); if (hasKey) result = m_getElementTable[key]; // May be null, even with the key. if (result == null && !hasKey) { result = GetEltFromDoc1(elementName, attrvals, doc); m_getElementTable[key] = result; // May still be null. } return result; }