【问题标题】:How to append binary data to a specific node at a specific place in an XML file如何将二进制数据附加到 XML 文件中特定位置的特定节点
【发布时间】:2011-03-30 18:02:54
【问题描述】:

我们正在使用 XML 文件来保存我们的数据,这都是双重的。由于我们的数据非常庞大,在 GB 的范围内,因此我们将其转换为字节以节省磁盘空间和访问时间。此外,我们正在以几 MB 的块写入数据,并且新的数据块也可以来自与前一个相同的源或来自不同的源。对于每个新源,我们在 XML 文件中创建了一个元素,以便将来轻松识别来自该源的数据。 我们面临的问题是,如何在 XML 文件中识别出一个源对应的元素,然后将该源对应的数据附加到 XML 文件中已经捕获的数据中。我正在使用 Linq to XML,但无法使用此方法搜索任何解决方案。我尝试了 XMLWriter 类,但使用它的问题是如何识别或到达我要为其编写块的元素。

【问题讨论】:

  • “将其转换为字节”到底是什么意思?这也是每个流都会做的事情。

标签: c# .net xml linq-to-xml


【解决方案1】:

XML 不是写入大量二进制数据的好格式(因为需要将二进制数据存储为 Base64 字符串或其他一些字符串安全编码),也不适合更新大文档中间的数据块.我建议重新考虑您的文件格式。

如果你必须使用 XML:

  • 确保您的字节数组在写入 XML 时采用 Base64 编码
  • 当你想在中间插入数据时,你必须复制 XML。考虑使用 XmlReader 和 XmlWriter。将源 XML 复制到您要添加数据的位置,将数据添加到输出写入器,然后完成 XML 的剩余部分的复制。
  • 避免将整个 XML 加载到内存中,因为这可能会导致 GB 范围的数据出现问题。

【讨论】:

    【解决方案2】:

    我确定我在这里没有完整的图片,但很难理解您为什么不为此使用数据库。不过,为了跟进 Alexei 的帖子,这里有一个人为的示例,说明如何使用 XmlReader 和 XmlWriter 来完成我认为您想做的事情:

    //start with some dummy data
    string bigData = "<bigdata><rec id='1'>1234</rec><rec id='2'>2468</rec></bigdata>";
    string criterion = "2";
    string append = "10";
    string newValue = "";
    bool match = false;
    StringBuilder sb = new StringBuilder();
    using (XmlWriter writer = XmlWriter.Create(sb))
    {
        using (XmlReader reader = XmlReader.Create(new StringReader(bigData)))
        {
        while (reader.Read())
        {
        switch (reader.NodeType)
        {
        case XmlNodeType.Element:
            if (reader.LocalName == "rec")
            {
                match = reader.GetAttribute("id").ToString() == criterion;
            }
            writer.WriteStartElement(reader.LocalName);
            writer.WriteAttributes(reader, true);
            if (reader.IsEmptyElement)
            {
                writer.WriteEndElement();
            }
            break;
        case XmlNodeType.Text: // do the append here
            newValue = match ? reader.Value + append : reader.Value;
            writer.WriteString(newValue);
            break;
        //other cases based on node types
        case XmlNodeType.EndElement:
            writer.WriteFullEndElement();
            break;
        }                                                                      
        }
            writer.Flush();
            string x = sb.ToString();//output
        }                         
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-18
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      • 2018-05-24
      • 2016-05-14
      • 2011-08-24
      • 2022-11-15
      相关资源
      最近更新 更多