仅序列化 xml 文件的一部分并保存它

本文关键字:保存 一部分 序列化 xml 文件 | 更新日期: 2023-09-27 18:35:08

我在XML序列化方面有问题。我将尝试用以下示例 xml 文件来解释它

<AutoExpo>
  <Details>
    <Venue>XYZ</Venue>
    <StartTime>09:00</StartTime>
    <EndTime>21:00</EndTime>
  </Details>
  <Cars>
      <Car>
        <Company>Chevrolet</Company>
        <Model>Cruz</Model>
        <Color>Red</Color>
      </Car>
      <Car>
        <Company>Ford</Company>
        <Model>Fiesta</Model>
        <Color>Blue</Color>
      </Car>
  </Cars>
</AutoExpo>

现在,当我读取这个 xml 文件时,我将汽车反序列化为对象。汽车清单可能很大。我的代码使用此对象,可以更改某些汽车的属性。现在,如果我只想序列化那些属性已更改的汽车对象,请返回到 xml 文件并保存它,以便下次我的代码启动时它获得最新的状态信息。

仅序列化 xml 文件的一部分并保存它

在XML文件中跳来跳去更改属性是相当困难的,无论它们在哪里更改。您应该将整个文件读入内存,并在保存时写出整个文件,覆盖旧文件。

XML并不是一个糟糕的方法,但据我从这个问题中可以看出,SQL Server(或其他RDBMS)数据库会更合适。您不必担心此类问题,因为数据库引擎会为您做到这一点。

尽管这可能不是最佳解决方案,但一个潜在的可行选择是将编辑的列表序列化为单独的文件,并在代码中比较这两个文件。如果信息没有任何更改,则两个文本文件应相同。如果没有,您可以将旧文件替换为新文件。最简单的方法是,与其序列化为文件并读取/写入文件,不如将其发送到流并进行比较。

序列化对象时,它将生成整个 XML 文档。 因此,如果您将其保存到文件中,它将覆盖该文件的先前内容。 因此,如果您希望生成的文件包含所有汽车,包括但不限于修改后的汽车,则需要序列化整个内容。 如果您只序列化已更改的汽车,则该文件将丢失所有未更改的汽车。 如果您确实只想序列化更改的汽车,我建议您创建 AutoExpo 对象的新实例,并且仅将要保存的汽车插入其中,然后仅使用部分列表序列化该对象。

如果由于数据太大而只需要修改 XML 中的单个元素而不触及其余元素,则 XML 不是一个好的选择。 我会建议使用关系数据库。 或者,您可以将每辆车存储为自己的XML文件,并且仅根据需要单独加载和保存每辆车。

你不能用XML做到这一点。请考虑使用关系数据库。关系数据库具有内置的文件空间管理机制,可以完全执行所需的操作。您可以更新单个记录,添加和删除记录。

Jet .mdb数据库 (Access) 是替换 XML 文件的良好候选项。您可以通过 OLEDB 访问它,但限制是应用程序必须编译为 32 位。无需安装访问权限。

首先,您的实体必须具有唯一标识符。

<AutoExpo>
  <Details>
    <Venue>XYZ</Venue>
    <StartTime>09:00</StartTime>
    <EndTime>21:00</EndTime>
  </Details>
  <Cars>
    <Car id="1">
      <Company>Chevrolet</Company>
      <Model>Cruz</Model>
      <Color>Red</Color>
    </Car>
    <Car id="2">
      <Company>Ford</Company>
      <Model>Fiesta</Model>
      <Color>Blue</Color>
    </Car>
  </Cars>
</AutoExpo>

现在,您可以使用 XPath 选择那些需要更新的节点并更改其内容。

  1. 将文档加载到 XDocument 中
  2. 找车:文件。元素("Car[id=2]")
  3. 设置新值:"元素。元素("颜色")。值 ="黑色"

但是,使用基于文件的存储的缺点仍然存在。您仍然需要将整个文件加载到内存中,并在更新时将其写回硬盘驱动器,但不必序列化所有 Car 对象。我想不出一种简单的方法来从硬盘驱动器流式传输文件并一次性操作它。