【问题标题】:XML serialization and LINQXML 序列化和 LINQ
【发布时间】:2009-12-17 01:04:30
【问题描述】:

我目前在我的数据库中有一个 XML 元素映射到一个对象(长话短说,XML 非常复杂和动态,足以挑战传统的关系数据结构,而不会造成巨大的性能损失)。

围绕它,我包装了一系列封装 XML 结构的 C# 对象。它们处理一个基类,并且有多个不同的可能类,它将使用不同的数据结构和不同的实现方法反序列化。我目前正在将序列化/反序列化这些功能包装到 LINQ 生成的数据库对象的部分类中。

我目前的做法是:

    public Options GetOptions()
    {
        if (XmlOptions == null) return null;
        XmlSerializer xs = new XmlSerializer(typeof(Options));
        return (Options)xs.Deserialize(XmlOptions.CreateReader());
    }

    public void SetOptions(Options options)
    {
        if (XmlOptions == null) Options = null;
        else
        {
            XmlSerializer xs = new XmlSerializer(typeof(Options));
            using (MemoryStream ms = new MemoryStream())
            {
                xs.Serialize(ms, options);
                XmlOptions = System.Xml.Linq.XElement.Parse(System.Text.UTF8Encoding.UTF8.GetString(ms.ToArray()));
            }
        }
    }

(鉴于更改的名称不太清楚,为了帮助阅读,XmlOptions 是 LINQ 中的 XElement 元素,Options 是我的反序列化类)

现在,它可以工作了。但这对我来说还不够“完成”:P 将 XML 序列化为内存流,将其转换为字符串,然后将其重新解析为 XML,这似乎是非常低效的。我的问题是 - 这是最干净的方法吗?是否有更有效/更整洁的序列化机制?有没有更好的方法可以给我同样的好处(目前我在系统中只有测试数据,所以如果需要我可以更改 XML 结构)?

PS:我已将这些字段重命名为更通用 - 所以不需要关于命名约定的 cmets ;)

【问题讨论】:

    标签: c# linq serialization


    【解决方案1】:

    XmlSerializer.Serialize 有一个overload that takes an XmlWriter

    您可以通过调用CreateWriter 方法创建一个写入现有XElementXmlWriter

    因此,您可以编写以下内容:

    static readonly XmlSerializer xs = new XmlSerializer(typeof(Options));
    
    ...
    
    var temp = new XElement("Parent");
    
    using (var writer = temp.CreateWriter())
        xs.Serialize(writer, options);
    
    XmlOptions = Temp.FirstNode;
    

    【讨论】:

    • 嘿,我试了一下,但我不断收到WriteStartDocument cannot be called on writers created with ConformanceLevel.Fragment.。我可以在网上找到的唯一建议是以XmlWriterSettings 的形式将设置放入XmlWriter.Create,但XElementCreateWriter 调用不接受编写器设置...
    • 那就不可能了。对不起。
    • 问题是 XElement 的作者有一个片段的一致性级别(一个元素只代表一个 Xml 文档的一个片段)。您必须创建一个 XDocument 并使用它的 CreateWriter 序列化到 - 这具有文档的一致性级别。然后您可以将 XDocument.Root 用作 XElement。
    • 如果XElementCreateWriter有一个额外的参数WriterSettings就好了。
    猜你喜欢
    • 1970-01-01
    • 2013-03-25
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多