如何使用XML声明将对象保持为可读的XML文件?

时间:2015-07-23 07:30:26

标签: c# xml persistence human-readable

背景

我正在开发一个可以创建/打开项目的桌面应用程序(想想visual studio)。我需要将这样的项目对象持久化到XML文件(想想.csproj)并从XML文件中加载该项目对象。

目标

  1. 将类MyProject存储/加载到XML文件
  2. 人类可读的XML(手动编辑很糟糕,但可以简化某些任务)
  3. 可以从其他语言/应用程序解析的有效XML:
    • 文件以<?xml version="1.1" encoding="utf-8"?>之类的XML声明开头,因为任何文化中的用户定义字符串都可能在此结束,因此编码很重要。另请参阅Does a valid XML file require an xml declaration?
    • 可以指定类名称空间(例如,通过DataContractAttribute.NameSpace
  4. 问:什么是将对象持久保存为可读性的最佳方式?有效的XML文件?

    有许多方法可以创建XML,对我而言,似乎[DataContract]属性是可行的方法,因为这允许简单的序列化和反序列化回到对象(目标1)。使用XmlTextWriter时,我还可以指定Formatting.Indented,它解决了目标2.但是,我无法创建XML声明。

    编辑:基于已接受答案的解决方案

    使用XmlTextWriter是死路一条,它不接受XmlWriterSettings。编写XML的方法太多(错误/错误)。使用具有所需设置的XmlWriter.Create(..)确实会产生人类可读的XML,包括声明。创建的实例是一些内部类,如WellFormedXmlWriter。代码:

        public static void Store<T>(string filename, T obj)
            where T : class
        {
            XmlWriterSettings settings = new XmlWriterSettings()
            {
                Indent = true, // human readable
                OmitXmlDeclaration = false, // don't omit the encoding
                Encoding = Encoding.UTF8
            };
            using (var xmlwriter = XmlWriter.Create(filename, settings))
            {
                DataContractSerializer ser = new DataContractSerializer(typeof(T));
                ser.WriteObject(xmlwriter, obj);
            }
        }
    
        public static T Load<T>(string filename)
            where T : class
        {
            using (var xmlReader = XmlReader.Create(filename))
            {
                DataContractSerializer ser = new DataContractSerializer(typeof(T));
                return (T)ser.ReadObject(xmlReader, true);
            }
        }
    

1 个答案:

答案 0 :(得分:1)

您可以将public void SetManagedNavigationin(string termSetName,Guid termSetGuid) { try { TaxonomySession taxonomySession = TaxonomySession.GetTaxonomySession(this.Ctx); taxonomySession.UpdateCache(); this.Ctx.Load(taxonomySession,ts => ts.TermStores); this.Ctx.ExecuteQuery(); //Throw error if no Term Stores are found if (taxonomySession.TermStores.Count == 0) throw new DeploymentException("TermStore Issue", new InvalidOperationException("Managed Metadata Service not found")); TermStore termStore = taxonomySession.TermStores[0]; this.Ctx.Load(termStore, ts => ts.Name, ts => ts.WorkingLanguage); this.Ctx.ExecuteQuery(); var existingTermSet = termStore.GetTermSet(termSetGuid); this.Ctx.Load(existingTermSet); this.Ctx.ExecuteQuery(); if (existingTermSet.ServerObjectIsNull.GetValueOrDefault()) { // Create a new Term Group for the Site Collection TermGroup siteCollectionGroup = termStore.GetSiteCollectionGroup(this.Ctx.Site, createIfMissing: true); TermSet termSet = siteCollectionGroup.CreateTermSet(termSetName, termSetGuid, termStore.WorkingLanguage); //Commit All Changes termStore.CommitAll(); this.Ctx.ExecuteQuery(); } //Reset the web object to the default settings var webNavigationSettings = new WebNavigationSettings(this.Ctx, this.Ctx.Web); webNavigationSettings.ResetToDefaults(); webNavigationSettings.GlobalNavigation.Source = StandardNavigationSource.TaxonomyProvider; webNavigationSettings.GlobalNavigation.TermStoreId = termStore.Id; webNavigationSettings.GlobalNavigation.TermSetId = termSetGuid; webNavigationSettings.Update(taxonomySession); //flush the cache TaxonomyNavigation.FlushSiteFromCache(this.Ctx, this.Ctx.Site); this.Ctx.ExecuteQuery(); } catch (Exception ex) { throw new DeploymentException("Managed Navigation setting Issue", ex); } } 实例传递给XmlWriterSettings,以便更精细地控制序列化。我相信XmlWriterSettings.OmitXmlDeclaration就是你所需要的。

There's a small overview of XML output formatting on MSDN.