将节点插入 XML 文件

Posted

技术标签:

【中文标题】将节点插入 XML 文件【英文标题】:Insert a node into a XML file 【发布时间】:2020-10-17 12:24:34 【问题描述】:

我正在尝试将单行/节点(如下提供)添加到 XML 中:

<Import Project=".www\temp.proj" Condition="Exists('.www\temp.proj')" />

该行可能位于 XML 的主/根节点下:

<Project Sdk="Microsoft.NET.Sdk">

我使用的方法:

        XmlDocument Proj = new XmlDocument();
        Proj.LoadXml(file);
        XmlElement root = Proj.DocumentElement;
        // Not sure about the next steps
        root.SetAttribute("not sure", "not sure", "not sure");

虽然我不完全知道如何在 XML 中添加该行,因为这是我第一次尝试直接编辑 XML 文件,但该错误导致了额外的问题。

我在第一次尝试时收到此错误:

C# "loadxml" '根级别的数据无效。第 1 行,位置 1。'

知道这个错误是一个著名的错误,有些人在此链接中提供了多种方法:

xml.LoadData - Data at the root level is invalid. Line 1, position 1

不幸的是,大多数解决方案都过时了,答案在这个案例上不起作用,我不知道如何在这个案例上应用其他人。

在该问题的链接上提供/接受的答案:

string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (xml.StartsWith(_byteOrderMarkUtf8))

    xml = xml.Remove(0, _byteOrderMarkUtf8.Length);

基本上它不起作用,因为xml.StartsWith似乎不再存在,同时xml.Remove也不存在。


您能否提供一段代码绕过错误并将该行添加到 XML 中?

编辑: cmets 部分提供了示例 XML 文件。

【问题讨论】:

可以分享一下原xml吗? 好的,请稍等。 在OneDrive:(名字不一样,不管你用哪个名字,我都可以编辑问题使其匹配)1drv.ms/u/s!AlScPmE9PLAKgTGcMhbWvznrT9NA?e=ijeEDx 【参考方案1】:

对于评论中发布的Xml,我使用了两种方法:

1 - XmlDocument

XmlDocument Proj = new XmlDocument();
Proj.Load(file);
XmlElement root = Proj.DocumentElement;
//Create node
XmlNode node = Proj.CreateNode(XmlNodeType.Element, "Import", null);

//create attributes
XmlAttribute attrP = Proj.CreateAttribute("Project");
attrP.Value = ".www\\temp.proj";

XmlAttribute attrC = Proj.CreateAttribute("Condition");
attrC.Value = "Exists('.www\\temp.proj')";

node.Attributes.Append(attrP);
node.Attributes.Append(attrC);

//Get node PropertyGroup, the new node will be inserted before it
XmlNode pG = Proj.SelectSingleNode("/Project/PropertyGroup");
root.InsertBefore(node, pG);

Console.WriteLine(root.OuterXml);

2 - Linq To Xml,使用XDocument

XDocument xDocument = XDocument.Load(file);

xDocument.Root.AddFirst(new XElement("Import", 
    new XAttribute[] 
     
        new XAttribute("Project", ".www\\temp.proj"), 
        new XAttribute("Condition", "Exists('.www\\temp.proj')") 
    ));

Console.WriteLine(xDocument);

要为XDocument 添加的命名空间:

using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

两种解决方案的结果相同,但最后一种很简单。

希望对您有所帮助。

【讨论】:

谢谢,抱歉来晚了,请花点时间看看你的好答案。 +1 两种方法都喜欢,它们清楚地显示了所需的步骤。如果您能够回答,有 2 个相关问题,首先是它是如何绕过该错误的? XML 是相同的,而且最初似乎都使用相同的方法(加载),它如何绕过关于第一个字符的疯狂错误? 其次,如果需要,如何在关闭根/包装元素 () 之前移动插入的行?就在最后一行之前?再次感谢。 @Kasrak 抱歉回复晚了,我会检查并回复你 1 个问题:它是如何绕过该错误的?您使用了.LoadXml(filePath) 而不是.Load(filePath),因为.LoadXml(filePath) 需要像参数一样的xml 字符串而不是文件路径。 2个问题:对于XmlDocument,使用.InsertAfter()代替.InsertBefore() likeroot.InsertAfter(node, pG);对于XDocument,使用.Add()代替.AddFirst() likexDocument.Root.Add(new ...)。我希望这能回答您的问题。【参考方案2】:

您是否可以使用官方的 MSBuild 库?(https://www.nuget.org/packages/Microsoft.Build/)我不确定仅读取和编辑项目文件实际上需要哪个 nuget 包。

我尝试过直接以编程方式编辑 MSBuild 项目文件,但不推荐。由于意外的变化,它经常中断...... MSBuild 库在编辑项目文件方面做得很好,例如添加属性、项目或导入。

【讨论】:

不,我有足够的 MSBuild 东西,这里我的问题是关于提到的问题。

以上是关于将节点插入 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

在 xml 文件中的特定节点之后插入一个节点

R:将节点插入到特定位置的xml树中

C#在xml文件中指定节点插入节点和属性

在特定位置插入 XML 节点

将 XML 数据插入到具有多个节点的 SQL 表中

将每个 xml 节点插入到 sql server 2008 表中