如何在c#中的xml之后添加数据并在之后读取xml?

Posted

技术标签:

【中文标题】如何在c#中的xml之后添加数据并在之后读取xml?【英文标题】:How to add data after xml in c# and read the xml after? 【发布时间】:2018-10-28 23:11:41 【问题描述】:

我必须创建一个带有 xml 标头的文件,然后我必须放入普通数据,就像这样:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Header>
  <Algorithm>alg</Algorithm>
  <nod2>aaa</nod2>
  <nod3>bbb</nod3>      
  <node>
    <User>
     <Email />
     <SessionKey />
     </User>
  </node>
</Header>
Data of the file....

我已经有了将其写入文件的代码。

该部分的代码:

private void setHeader(FileStream output, string nod2, string nod3, string )
            
    XmlDocument doc = new XmlDocument();
    XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
    doc.AppendChild(docNode);

    XmlNode header = doc.CreateElement("Header");
    doc.AppendChild(header);

    XmlNode algorithm = doc.CreateElement("Algorithm");
    algorithm.InnerText = "alg";
    header.AppendChild(algorithm);
    XmlNode node2= doc.CreateElement("nod2");
    node2.InnerText = nod2;
    header.AppendChild(node2);
    XmlNode node3= doc.CreateElement("nod3");
    node3.InnerText = nod3;
    header.AppendChild(node3);

    XmlNode node= doc.CreateElement("node");
    header.AppendChild(node);

    XmlNode user1 = doc.CreateElement("User");
    node.AppendChild(user1);

    XmlNode mail = doc.CreateElement("Email");
    user1.AppendChild(mail);
    XmlNode sessionKey = doc.CreateElement("SessionKey");
    user1.AppendChild(sessionKey);

    doc.Save(output);            

它工作得很好,但是当我想阅读它时

private void readHeader(FileStream input, out string algorithm)

    XmlDocument doc = new XmlDocument();
    doc.Load(input);

当“文件的数据...”启动时出现错误:“根级别的数据无效”。 有没有办法在整个 xml 之后处理数据,或者让我将数据添加为节点?

【问题讨论】:

“效果很好” -- 你怎么知道?它甚至不编译。请向我们展示您的实际代码。如果问题顶部的示例“XML”是您真正生成的,则它不是有效的 XML。 我将它用于加密和解密文件的程序。 xml部分应该描述加密设置,在原始文件的加密数据之后并且它不在任何节点内。因此,当我生成文件并用记事本打开它时,它看起来就像我被要求做的那样,就像顶部的 xml 一样。节点外的数据是否无效?如果是,是否有一种简单的方法来读取有效 xml 的标头并忽略不在节点中的数据? "它不在任何节点内" -- 如果是这样,您无法使用 XML 解析器解析文件。您有两个选择: 1. 分别解析标头; 2:将数据放在XML本身的CDATA块中:&lt;File&gt;&lt;Header&gt;...&lt;/Header&gt;&lt;Data&gt;&lt;![CDATA[ ... ]]&gt;&lt;/Data&gt;&lt;/File&gt;。我认为你会对加密数据进行 Base64 编码。 是的,you'll need to encode the encrypted data 在 CDATA 块中。这是迄今为止首选的方法。 我也希望将它放在一个节点中,但我被要求以其他方式进行:/ 感谢您的帮助 :) 【参考方案1】:

这可以通过多种方式完成。在 cmets 中,您已经指出由于讨论范围之外的原因,最好的方法是不可接受的。为了完整起见,我还是要把那个放在第一位。跳到 tl;dr 了解我认为你最终必须要做的事情。

执行此操作的首选方法是base64 encode 加密数据并将其放入 CDATA 块中:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<File>
    <Header>
      <Algorithm>alg</Algorithm>
      <nod2>aaa</nod2>
      <nod3>bbb</nod3>      
      <node>
        <User>
         <Email />
         <SessionKey />
         </User>
      </node>
    </Header>
    <Data><![CDATA[
    ICAgIFhtbE5vZGUgYWxnb3JpdGhtID0gZG9jLkNyZWF0ZUVsZW1lbnQoIkFsZ29yaXRobSIpOw0K
    ICAgIGFsZ29yaXRobS5Jbm5lclRleHQgPSAiYWxnIjsNCiAgICBoZWFkZXIuQXBwZW5kQ2hpbGQo
    YWxnb3JpdGhtKTsNCiAgICBYbWxOb2RlIG5vZGUyPSBkb2MuQ3JlYXRlRWxlbWVudCgibm9kMiIp
    Ow0KICAgIG5vZGUyLklubmVyVGV4dCA9IG5vZDI7DQogICAgaGVhZGVyLkFwcGVuZENoaWxkKG5v
    ZGUyKTsNCiAgICBYbWxOb2RlIG5vZGUzPSBkb2MuQ3JlYXRlRWxlbWVudCgibm9kMyIpOw0KICAg
    IG5vZGUzLklubmVyVGV4dCA9IG5vZDM7DQogICAgaGVhZGVyLkFwcGVuZENoaWxkKG5vZGUzKTs=
    ]]></Data>
</File>

这是这个问题的规范答案。

但你告诉我,在你的情况下,你不能那样做。

Second choice is MIME(实际上,MIME 可能是第一选择,上面可能是第二选择)。但我感觉他们也不喜欢 MIME。

第三种选择,将文件作为字符串读取并搜索插入在 XML 和二进制数据之间的某个标记,something like a MIME boundary。

tl;博士

如果他们不允许您在文件中添加这样的标记(我敢打赌他们不会),请搜索第一次出现的子字符串 "&lt;/Header&gt;"

var xml = File.ReadAllText(filePath);
var endTag = "</Header>";

var headerXML = xml.Substring(0, xml.IndexOf(endTag) + endTag.Length);

var xdHeader = new XmlDocument();
xdHeader.LoadXml(headerXML);

【讨论】:

【参考方案2】:

我通过直接写入文件 doc.Save(@"c:\temp\test1.xml"); 测试了您的代码 从该文件加载工作正常。所以你的xml文档没有问题。检查您的文件流。您是否正确冲洗并关闭它?它有 UTF-8 编码吗? 节点字符串中的输入是什么。根据 xml 规则,没有什么是无效的?

【讨论】:

我将它用于加密和解密文件的程序。 xml部分应该描述加密设置,在原始文件的加密数据之后并且它不在任何节点内。所以当我生成文件并用记事本打开它时,它看起来就像我被要求做的那样,就像顶部的 xml 一样。节点外的数据是否无效?如果是,是否有一种简单的方法可以只读取有效 xml 的标头并忽略不在节点中的数据?【参考方案3】:

在单个根节点之后,只有cmets和处理器指令可以写入xml。因此,您可以尝试将数据写入 cmets。

看起来像这样:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Header>
  ...
</Header>
<!-- your data -->
<!-- another data -->

此方法有limitations:您的数据可能不包含--(双连字符)并且可能不以- 结尾。

但当然最好不要这样做。

【讨论】:

以上是关于如何在c#中的xml之后添加数据并在之后读取xml?的主要内容,如果未能解决你的问题,请参考以下文章

在c#的winform 下怎么读取 xml文件中的数据?

在c#的winform 下怎么读取 xml文件中的数据?

C#中的Linq to Xml详解

c#中xml文件

c#中怎样读取xml文件中的数据,怎样动态将数据存储到xml文件中去?

C# 如何读取xml文件并输出信息到label上