【问题标题】:Serialize data from xml model into custom binary format将 xml 模型中的数据序列化为自定义二进制格式
【发布时间】:2016-03-05 08:38:19
【问题描述】:

我在这里寻找有关如何处理我的问题的建议,并了解是否已经有一些工具可以像这样工作,但我不知道...... 好吧,我必须使用他们的自定义二进制文件格式将大量数据从我的系统传递到另一个系统来交换数据。 我有许多(类似 tlv 的)二进制文件要生成,我正在寻找如何实现我的目标而无需手写太多代码,因为有人告诉我 文件格式很快就会发展起来。

例如,这是我系统中的 2 个表(产品列表及其不同 iso 代码的标签):

产品表:

---------
SAL_产品
----------
编号 (3)
VENDOR_ID NUMBER (3)
MODEL_REF VARCHAR2(30)
----------


产品标签表:

---------
SAL_PRODUCT_LABEL
----------
PRODUCT_ID NUMBER(3)
ISO_LANG_CODE VARCHAR2(5)
标签 VARCHAR2(40)
----------


我必须生成一个类似于此结构的二进制文件:

  • [Byte-size]
  • [Elm-count]

    • [Byte-size]

    • [ID]

    • [VENDORID]

      • [Elm-count]

        • [Byte-size]

        • [LANG_ID]

        • [LABELID]

我发现我必须创建一个能够处理 xml 元数据文件的文件生成器:

<messages type="product" select="select ID,VENDOR_ID, MODEL_REF from SAL_PRODUCT order by 1">

    <message>

        <prop type="ID"/>
        <prop type="VENDOR_ID" />

        <messages type="labels" select="select product_id, ISO_LANG_CODE as LANGID, LABEL from  SAL_PRODUCT_LABEL" joinclause="product.ID = labels.product_id " >

           <message  >  
            <prop type="LANGID" />
            <prop type="LABEL" />
           </message>


        </messages>

        <prop type="MODEL_REF"/>

    </message>  


</messages>     

但是我所有的 C# 代码都应该是动态的,并且能够解析和使用嵌套结构...... 从这里我不知道如何处理我的问题:

  • 我是否选择了正确的解决方案?

  • 您将如何处理此类问题?

感谢您的帮助

【问题讨论】:

    标签: c# serialization recursive-datastructures


    【解决方案1】:

    最简单的方法之一是通过以下两个步骤进行:

    1。创建强类型模型类

    使用强类型模型类。它们可以是手写的/generated 类以将 XML 反序列化为,或者,如果您使用一些现有的数据库存储,则可以使用 Entity Framework database first approach 从现有的数据库表中创建它们。

    它会给你什么? - 你的数据不需要任何自定义描述符(我的意思是那些看起来不那么漂亮的 XML 格式描述符)。数据模型将自行定义其格式(可能还有一些属性),并且由于管理不善或序列化配置不是最新而可能出现错误的风险将大大降低。

    有什么缺点吗? - 嗯,它不会那么容易版本化(我的意思是序列化或反序列化旧文件) - 你必须为每个版本使用一个模型(比如 ModelV1, ModelV2... ) 和每个二进制文件格式版本 (SerializerFormatV1, SerializerFormatV2...) 的一个序列化程序。但如果采用动态结构,实现起来会更加困难。

    2。创建自定义序列化程序

    据我所知,.NET 框架没有提供任何标准的序列化-反序列化基础架构,您可以轻松地将自定义序列化程序集成到其中。

    嗯,有 ISerializable 接口和它上面的整个基础设施 - https://msdn.microsoft.com/en-us/library/ty01x675(v=vs.110).aspx ,但这主要是 .NET 2.0 时代技术(DataContractSerializer 或 Protobuf/Newtonsoft.Json 序列化框架中没有使用)。而坚持下去,你将一无所获。

    所以您应该只实现自定义序列化程序,它会反映您的模型类型的属性并根据该自定义二进制格式写入数据。

    如何枚举所有属性 - Recursively Get Properties & Child Properties Of A Class

    类似的自定义序列化程序示例(仅适用于纯文本文件)-Custom serialization of an object in .NET

    会是这样的:

    public class OtherCompanyBinaryFormatSerializer
    {
        public void Serialize<T>(Stream stream, T object); { ... }
        public T Deserialize<T>(Stream stream); { ... }
    }
    

    还有一些事情你应该注意:

    1. 嵌套结构 - 在枚举属性时不要忘记正确递归以序列化嵌套结构。
    2. 循环参考 - 这有点困难,我找不到任何好的建议。但如果你的数据不能有这样的东西,那么你可能是安全的。
    3. 版本控制 - 曾几何时,格式会发生变化,无论是您自己的数据还是该二进制文件格式。但是您仍然需要处理旧数据。如何处理?正如我在第 1 步中已经说过的 - 带有版本标记的数据和序列化程序。一些关于“版本容错序列化”的互联网搜索会给你更多的想法。

    【讨论】:

    • 感谢您的反馈。我必须补充的是,我愿意成为动态的:从某种意义上说,我希望只有这个 xml 配置文件可以保存所有配置,并让我即时重塑输出文件以及更改sql查询,无需重新编译等...
    • 我不知道该怎么做是让子查询引用上下文顶级查询(请参阅问题中的我的连接子句)...
    • @Dypso 如果没有那么多不同的查询,你可以直接在代码中处理它们——然后序列化结果。但如果您认为需要大量此类查询,请查看stackoverflow.com/questions/9505189/…stackoverflow.com/questions/217961/…。只是不要成为具有这种可配置性的en.wikipedia.org/wiki/Inner-platform_effect 的受害者。在大多数情况下,这是不必要的,会降低性能并且很容易出错。
    猜你喜欢
    • 2022-08-16
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多