private void ProcessTermStore(XElement xmlNode, LocalTermStore termStore) { this.ReadTaxmlComments(xmlNode, termStore); int?defaultLanguge = GetIntegerAttributeValue(xmlNode, TaxmlSpec.DefaultLanguageToken); if (defaultLanguge != null) { termStore.DefaultLanguageLcid = defaultLanguge.Value; } else { termStore.DefaultLanguageLcid = LocalTermStore.EnglishLanguageLcid; } // Stage 1: Create everything that can be immediately created foreach (XElement childNode in xmlNode.Elements()) { switch (childNode.Name.LocalName) { case TaxmlSpec.TermSetGroupToken: this.ProcessTermSetGroup(childNode, termStore); break; case TaxmlSpec.SyncActionToken: this.ProcessSyncAction(childNode, termStore); break; default: throw new ParseException("Unimplemented XML tag \"" + childNode.Name.LocalName + "\"", childNode); } } }
public void SaveToFile(string fileName, LocalTermStore termStore) { using (StreamWriter streamWriter = new StreamWriter(fileName)) { this.SaveToStream(streamWriter, termStore); } }
public static string SaveToString(LocalTermStore termStore) { using (var writer = new StringWriter()) { TaxmlSaver saver = new TaxmlSaver(); saver.SaveToStream(writer, termStore); return(writer.ToString()); } }
protected void SetParentItem <T>(ref T parentItem, T newValue) where T : LocalTaxonomyItem { if (parentItem == newValue) { return; } if (newValue != null) { string objection = newValue.ExplainIsAllowableParentFor(this); if (objection != null) { throw new InvalidOperationException(objection); } if (newValue.defaultLanguageLcid != this.defaultLanguageLcid) { // We could do this automatically, but changing the default langauge can // cause copying of term labels whose effects may be counterintuitive. // In most cases, the child object should have been created with the same // default language as its intended parent. throw new InvalidOperationException("The child object cannot be attached" + " unless its default language matches the parent."); } } if (parentItem != null) { LocalTermStore oldTermStore = parentItem.GetTermStore(); if (oldTermStore != null) { oldTermStore.OnBeforeRemoveSubtree(this); } parentItem.OnRemoveChildItem(this); } if (newValue != null) { LocalTermStore newTermStore = newValue.GetTermStore(); if (newTermStore != null) { newTermStore.OnBeforeAddSubtree(this); } } LocalTaxonomyItem oldValue = parentItem; parentItem = newValue; if (parentItem != null) { parentItem.OnAddChildItem(this); } this.OnParentItemChanged(oldValue, newValue); }
private void ProcessTermSetGroup(XElement xmlNode, LocalTermStore termStore) { string name = this.GetRequiredAttributeValue(xmlNode, TaxmlSpec.NameToken); if (TaxmlSpec.IsReservedName(name)) { // TODO: Handle system groups here throw new NotImplementedException(); } Guid id = this.GetGuidAttributeValue(xmlNode, TaxmlSpec.IdToken) ?? Guid.Empty; LocalTermGroup termGroup = new LocalTermGroup(id, name, termStore.DefaultLanguageLcid); this.ReadTaxmlComments(xmlNode, termGroup); string description = this.GetAttributeValue(xmlNode, TaxmlSpec.DescriptionToken); if (description != null) { termGroup.Description = description; } // Add the group to the term store termStore.AddTermGroup(termGroup); bool processedDescription = false; foreach (XElement childNode in xmlNode.Elements()) { switch (childNode.Name.LocalName) { case TaxmlSpec.DescriptionToken: if (processedDescription) { throw new ParseException("The description cannot be specified more than once", childNode); } processedDescription = true; termGroup.Description = childNode.Value; break; case TaxmlSpec.TermSetToken: this.ProcessTermSet(childNode, termGroup); break; case TaxmlSpec.SyncActionToken: this.ProcessSyncAction(childNode, termGroup); break; default: throw new ParseException("Unimplemented XML tag \"" + childNode.Name.LocalName + "\"", childNode); } } }
public LocalTermStore LoadFromFile(string csvFileName) { LocalTermStore termStore = new LocalTermStore(Guid.Empty, "Term Store"); LocalTermGroup termGroup = termStore.AddTermGroup(Guid.Empty, Path.GetFileNameWithoutExtension(csvFileName)); using (CsvReader csvReader = new CsvReader(csvFileName)) { csvReader.WrapExceptions(() => { ProcessCsvLines(termGroup, csvReader); }); } return(termStore); }
public LocalTermStore LoadFromStream(TextReader textReader) { XDocument document = XDocument.Load(textReader, LoadOptions.SetLineInfo); document.Validate(TaxmlSpec.TaxmlSchema, delegate(object sender, ValidationEventArgs e) { throw new ParseException(e.Message, sender as XObject, e.Exception); } ); LocalTermStore termStore = new LocalTermStore(Guid.NewGuid(), "Term Store"); XElement rootElement = document.Root; XElement termStoreElement; if (rootElement.Name == TaxmlSpec.TermStoreToken) { // For backwards compatibility, if the root element is the "TermStore" element // then wrap it inside a TaxmlFile element termStoreElement = rootElement; rootElement = new XElement(TaxmlSpec.TaxmlFileToken, termStoreElement); rootElement.SetAttributeValue(TaxmlSpec.VersionToken, TaxmlSpec.Versions.V2_0.ToString()); } else { termStoreElement = rootElement.Element(TaxmlSpec.TermStoreToken); } // Check the version string versionString = this.GetAttributeValue(rootElement, TaxmlSpec.VersionToken); Version fileVersion = Version.Parse(versionString); if (fileVersion < TaxmlSpec.Versions.OldestLoadable) { throw new InvalidOperationException( "The TAXML file version is too old and is no longer supported by this tool"); } if (fileVersion > TaxmlSpec.Versions.Current) { throw new InvalidOperationException( "The TAXML file is using a newer version that is not supported; consider upgrading to a newer tool"); } this.ProcessTermStore(termStoreElement, termStore); return(termStore); }
public void SaveToStream(TextWriter textWriter, LocalTermStore termStore) { XElement rootElement = new XElement(TaxmlSpec.TaxmlFileToken); rootElement.SetAttributeValue(TaxmlSpec.VersionToken, TaxmlSpec.Versions.Current.ToString()); XDocument xmlDocument = new XDocument( new XDeclaration("1.0", "utf-8", "yes"), rootElement ); this.ProcessTree(rootElement, termStore); var xmlWriterSettings = new XmlWriterSettings() { Indent = true, IndentChars = " " }; using (var xmlWriter = XmlWriter.Create(textWriter, xmlWriterSettings)) { xmlDocument.Save(xmlWriter); } textWriter.WriteLine(); // append a newline #if DEBUG // Verify that the generated XML conforms to the schema xmlDocument.Validate(TaxmlSpec.TaxmlSchema, delegate(object sender, ValidationEventArgs e) { throw new ParseException(e.Message, sender as XObject, e.Exception); } ); #endif }
protected override void SetParentItem(LocalTaxonomyItem value) { this.ParentItem = (LocalTermStore)value; }
private void ProcessChildTerms(XElement termContainerElement, LocalTermContainer termContainer, List <CustomOrderedTerm> orderedTerms) { LocalTermStore termStore = termContainer.GetTermStore(); foreach (CustomOrderedTerm customOrderedTerm in orderedTerms) { LocalTerm term = customOrderedTerm.Term; bool isTermLink = term.TermKind != LocalTermKind.NormalTerm; XElement termElement; if (isTermLink) { termElement = new XElement(TaxmlSpec.TermLinkToken); if (term.TermKind == LocalTermKind.TermLinkUsingId && term.TermLinkNameHint.Length > 0) { termElement.Add(new XAttribute(TaxmlSpec.NameHintToken, term.TermLinkNameHint)); } } else { termElement = new XElement(TaxmlSpec.TermToken, new XAttribute(TaxmlSpec.NameToken, term.Name)); } termContainerElement.Add(termElement); this.ProcessTaxmlComments(termElement, term); if (term.Id != Guid.Empty) { termElement.Add(new XAttribute(TaxmlSpec.IdToken, term.Id.ToString("B"))); } if (customOrderedTerm.WriteInOrderAttribute) { if (termContainer.CustomSortOrder.Contains(term.Id)) { termElement.Add(new XAttribute(TaxmlSpec.InOrderToken, true)); } } if (!term.IsAvailableForTagging) { termElement.Add(new XAttribute(TaxmlSpec.IsAvailableForTaggingToken, false)); } this.ProcessSyncActionElement(term, termElement); if (isTermLink) { if (!string.IsNullOrWhiteSpace(term.TermLinkSourcePath)) { termElement.Add(new XAttribute(TaxmlSpec.TermLinkSourcePathToken, term.TermLinkSourcePath)); } if (term.IsPinnedRoot) { termElement.Add(new XAttribute(TaxmlSpec.IsPinnedRootToken, true)); } } else { // TODO: If the Term.Owner is the same as the parent object, can we omit it? if (!string.IsNullOrEmpty(term.Owner)) { termElement.Add(new XAttribute(TaxmlSpec.OwnerToken, term.Owner)); } if (term.IsDeprecated) { termElement.Add(new XAttribute(TaxmlSpec.IsDeprecatedToken, true)); } foreach (LocalizedString description in term.Descriptions) { XElement descriptionElement = new XElement(TaxmlSpec.LocalizedDescriptionToken, description); termElement.Add(descriptionElement); if (description.Lcid != term.DefaultLanguageLcid) { descriptionElement.Add(new XAttribute(TaxmlSpec.LanguageToken, description.Lcid)); descriptionElement.Value = description.Value; } } this.ProcessCustomProperties(term.CustomProperties, termElement, isLocal: false); } this.ProcessCustomProperties(term.LocalCustomProperties, termElement, isLocal: true); List <CustomOrderedTerm> orderedChildTerms = this.ProcessCustomSortOrder(term, termElement); if (!isTermLink) { foreach (LocalTermLabel label in term.Labels) { // If this is the Term.Name label, then it doesn't need to be specified explicitly if (label.IsDefault && label.Lcid == term.DefaultLanguageLcid) { continue; } XElement labelElement = new XElement(TaxmlSpec.LabelToken, label.Value); termElement.Add(labelElement); if (label.Lcid != term.DefaultLanguageLcid) { labelElement.Add(new XAttribute(TaxmlSpec.LanguageToken, label.Lcid)); } if (label.IsDefault) { labelElement.Add(new XAttribute(TaxmlSpec.IsDefaultForLanguageToken, true)); } } } this.ProcessChildTerms(termElement, term, orderedChildTerms); } }
private void ProcessTree(XElement rootElement, LocalTermStore termStore) { XElement termStoreElement = new XElement(TaxmlSpec.TermStoreToken); rootElement.Add(termStoreElement); termStoreElement.SetAttributeValue(TaxmlSpec.DefaultLanguageToken, termStore.DefaultLanguageLcid); this.ProcessTaxmlComments(termStoreElement, termStore); this.ProcessSyncActionElement(termStore, termStoreElement); foreach (LocalTermGroup termGroup in termStore.TermGroups) { // Replace e.g. "System" with the reserved symbol "|SystemGroup|" string adjustedGroupName = termGroup.Name; if (termGroup.IsSystemGroup) { adjustedGroupName = TaxmlSpec.SystemGroupReservedName; } XElement groupElement = new XElement(TaxmlSpec.TermSetGroupToken, new XAttribute(TaxmlSpec.NameToken, adjustedGroupName)); termStoreElement.Add(groupElement); this.ProcessTaxmlComments(groupElement, termGroup); if (termGroup.Id != Guid.Empty) { groupElement.Add(new XAttribute(TaxmlSpec.IdToken, termGroup.Id.ToString("B"))); } this.ProcessSyncActionElement(termGroup, groupElement); if (!string.IsNullOrEmpty(termGroup.Description)) { groupElement.Add(new XElement(TaxmlSpec.DescriptionToken, termGroup.Description)); } foreach (LocalTermSet termSet in termGroup.TermSets) { bool isOrphanedTermsTermSet = false; bool isKeywordsTermSet = false; // Replace e.g. "Orphaned Terms" with the reserved symbol "|OrphanedTermsTermSet|" string adjustedTermSetName = termSet.Name; #if false // TODO if (termGroup.IsSystemGroup) { if (termSet.Id == termStore.OrphanedTermsTermSet.Id) { adjustedTermSetName = TaxmlSpec.OrphanedTermsTermSetReservedName; isOrphanedTermsTermSet = true; } else if (termSet.Id == this.termStoreAdapter.KeywordsTermSet.Id) { adjustedTermSetName = TaxmlSpec.KeywordsTermSetReservedName; isKeywordsTermSet = true; } } #endif XElement termSetElement = new XElement(TaxmlSpec.TermSetToken, new XAttribute(TaxmlSpec.NameToken, adjustedTermSetName)); groupElement.Add(termSetElement); this.ProcessTaxmlComments(termSetElement, termSet); this.ProcessSyncActionElement(termSet, termSetElement); if (!isOrphanedTermsTermSet && !isKeywordsTermSet) { if (termSet.Id != Guid.Empty) { termSetElement.Add(new XAttribute(TaxmlSpec.IdToken, termSet.Id.ToString("B"))); } if (!termSet.IsAvailableForTagging) { termSetElement.Add(new XAttribute(TaxmlSpec.IsAvailableForTaggingToken, false)); } if (termSet.IsOpenForTermCreation) { termSetElement.Add(new XAttribute(TaxmlSpec.IsOpenForTermCreationToken, true)); } } if (!string.IsNullOrEmpty(termSet.Owner) && !isKeywordsTermSet) { termSetElement.Add(new XAttribute(TaxmlSpec.OwnerToken, termSet.Owner)); } if (!string.IsNullOrEmpty(termSet.Contact) && !isKeywordsTermSet) { termSetElement.Add(new XAttribute(TaxmlSpec.ContactToken, termSet.Contact)); } foreach (var localizedName in termSet.LocalizedNames) { if (localizedName.Lcid != termSet.DefaultLanguageLcid) { termSetElement.Add( new XElement(TaxmlSpec.LocalizedNameToken, localizedName, new XAttribute(TaxmlSpec.LanguageToken, localizedName.Lcid)) ); } } // Technically the TermSet.Description property can be modified for the special "Keywords" // term set, but it's not recommended, so we don't support that if (!string.IsNullOrEmpty(termSet.Description) && !isOrphanedTermsTermSet && !isKeywordsTermSet) { termSetElement.Add(new XElement(TaxmlSpec.DescriptionToken, termSet.Description)); } this.ProcessCustomProperties(termSet.CustomProperties, termSetElement, isLocal: false); List <CustomOrderedTerm> orderedChildTerms = this.ProcessCustomSortOrder(termSet, termSetElement); foreach (string stakeholder in termSet.Stakeholders) { termSetElement.Add(new XElement(TaxmlSpec.StakeHolderToken, stakeholder)); } this.ProcessChildTerms(termSetElement, termSet, orderedChildTerms); } } }