如何在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块中:<File><Header>...</Header><Data><![CDATA[ ... ]]></Data></File>
。我认为你会对加密数据进行 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;博士
如果他们不允许您在文件中添加这样的标记(我敢打赌他们不会),请搜索第一次出现的子字符串 "</Header>"
:
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?的主要内容,如果未能解决你的问题,请参考以下文章