首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >序列化和语法分析相结合的方法?

序列化和语法分析相结合的方法?
EN

Stack Overflow用户
提问于 2011-02-03 09:58:45
回答 2查看 340关注 0票数 4

我遇到了一个两难的问题。我的C#应用程序使用一种自定义文件格式,需要在文本编辑器中可供人类编辑,但也可以通过应用程序中的图形用户界面进行编辑。这个文件将表示一个顶级对象(称为TopObject),它包含几个较小的对象,而这些对象又包含其他对象,依此类推。这些对象中包含的所有数据都在文件中提供。

我陷入了如何加载/保存这些文件的问题。C#序列化不适合我,因为它破坏了人工可编辑性(二进制序列化),或者在序列化基类集合时有“问题”(XML和DataContract序列化,它们在序列化基类时添加文本来消除派生类的歧义,这使得文件更容易被人类编辑);如果不是因为需要手动编辑文件,它就是门票。我一直在研究诸如GOLD和GPLEX/GPPG这样的解析器生成器来解析文件并将其转换为它们所表示的对象,这看起来很有希望,但这只涵盖了加载文件的一个方向,并不能确保在写出文件时将它们保存为正确的格式。

最好的方法是指定一种同时处理以下两种情况的语法:

1)读取具有指定结构的文件,并将其转换为TopObject及其包含的所有对象,以及

2)给定一个TopObject,将其状态写到具有相同结构的文件中。

在很大程度上,只需要一个语法就可以实现导入结构和输出结构。

有没有这样的工具或框架可以帮助我?这是可行的吗,还是我想太多了,有一种更简单的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-03 10:06:36

我仍然会使用XML,但只需编写您自己的序列化程序。您可以使用.Net中的XML读取器/写入器类来创建一个简单的XML格式:

代码语言:javascript
复制
<TopObject>
    <SubObject>
        <SubObject>
            etc.
        </SubObject>  
        <SubObject>
            etc.
        </SubObject>
    </SubObject>
    <SubObject></SubObject>
</TopObject>

我不知道您是否认为这足够人类可读,但最好是.Net序列化程序创建的东西。以递归方式读/写将非常简单。

示例:

这里有一个您可以适应的简单示例。假设我有这样的类:

代码语言:javascript
复制
public class Node {
    public Node(String _SomeProperty) {
        this.SomeProperty = _SomeProperty;
    }

    public String SomeProperty;

    public List<Node> Children = new List<Node>();
}

每个Node都有一个称为SomeProperty的属性。它也可以有孩子;在Children属性中有更多的Nodes

下面是一个控制台应用程序的main,它从这个类中创建一些数据进行序列化:

代码语言:javascript
复制
static void Main(string[] args) {
    // Make some data for testing
    Node baseObject = new Node("This is the base class");

    List<Node> Children = new List<Node>(){
        new Node("This is a child"),
        new Node("This is another child")
    };

    baseObject.Children = Children;

    Node aSubChild = new Node("This is a child of a child");
    baseObject.Children[0].Children = new List<Node>() { aSubChild };

    // Serialize

    XmlWriter writer = XmlWriter.Create("test.xml");

    writer.WriteStartDocument();


    RecursivelySerialize(ref writer, baseObject);
    writer.Flush();
}

它调用一个名为RecursivelySerialize的方法,该方法执行实际的工作:

代码语言:javascript
复制
private static void RecursivelySerialize(ref XmlWriter writer, Node sc) {
    writer.WriteStartElement("Node");

    writer.WriteElementString("SomeProperty", sc.SomeProperty);

    if (sc.Children.Count > 0) {
        writer.WriteStartElement("Nodes");

        foreach (Node scChild in sc.Children)
            RecursivelySerialize(ref writer, scChild);

        writer.WriteEndElement();
    }

    writer.WriteEndElement();
}

这个方法并不复杂。为了改进它,您可以使用反射来动态序列化任何类型的类。下面是我在运行上面的代码时得到的输出(格式很好):

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<Node>
    <SomeProperty>This is the base class</SomeProperty>
    <Nodes>
        <Node>
            <SomeProperty>This is a child</SomeProperty>
                <Nodes>
                    <Node>
                        <SomeProperty>This is a child of a child</SomeProperty>
                    </Node>
                </Nodes>
        </Node>
        <Node>
            <SomeProperty>This is another child</SomeProperty>
        </Node>
    </Nodes>
</Node>
票数 4
EN

Stack Overflow用户

发布于 2011-02-04 08:38:52

就我个人而言,我不会花太多时间让文件可供人类编辑,至少不能由非技术人员编辑。如果应用程序需要使用文件,那么它将需要准确性,并且无论您建立哪种语法,人类仍然会犯错误。

XML/JSON/INIs对于一些技术人员来说仍然很难不搞砸(令人惊讶),但至少对一些技术人员来说它们是熟悉的。我认为这些都是比滚动你自己的语法更好的选择。更好的是,如果你想让编辑文件变得更加用户友好,你可以考虑放弃“人类可编辑”的要求,使其只能由应用程序编辑。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4881983

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档