繁体   English   中英

使用LINQ在文档C#中的特定点插入新XML数据

[英]Inserting new XML Data at specific Point in document C# Using LINQ

大家好,我整天都在寻找可以使用LINQ将数据添加到现有XML文档中的方法。 我似乎只能找到如何创建新元素以及如何将它们添加到文件末尾。 我正在尝试创建一个应用程序,该应用程序允许我添加FTP帐户并从Filezilla Ftp客户端更新现有帐户,而无需手动执行。 这是XML文档。

    <FileZillaServer>
  <Settings>
    <Item name="Admin port" type="numeric">14147</Item>
  </Settings>
  <Groups />
  <Users>
    <User Name="ServerManager">
      <Option Name="Pass">6</Option>
      <Option Name="Group">
      </Option>
      <Option Name="Bypass server userlimit">0</Option>
      <Option Name="User Limit">0</Option>
      <Option Name="IP Limit">0</Option>
      <Option Name="Enabled">1</Option>
      <Option Name="Comments">
      </Option>
      <Option Name="ForceSsl">0</Option>
      <IpFilter>
        <Disallowed />
        <Allowed />
      </IpFilter>
      <Permissions>
        <Permission Dir="C:\Dayz Server Manager">
          <Option Name="FileRead">1</Option>
          <Option Name="FileWrite">1</Option>
          <Option Name="FileDelete">1</Option>
          <Option Name="FileAppend">1</Option>
          <Option Name="DirCreate">1</Option>
          <Option Name="DirDelete">1</Option>
          <Option Name="DirList">1</Option>
          <Option Name="DirSubdirs">1</Option>
          <Option Name="IsHome">1</Option>
          <Option Name="AutoCreate">0</Option>
        </Permission>
        <Permission />
      </Permissions>
      <SpeedLimits DlType="0" DlLimit="10" ServerDlLimitBypass="0" UlType="0" UlLimit="10" ServerUlLimitBypass="0">
        <Download />
        <Upload />
      </SpeedLimits>
    </User>
  </Users>
</FileZillaServer>

到目前为止,我已经能够弄清楚如何使用LINQ查询进入文档的正确位置,但是还不确定如何添加到文档中。 任何帮助将不胜感激。 以下是我用来使我处于正确位置的查询。

                var InsHere = from name in doc.Descendants("Users")
                           where name.Element("User").Attribute("Name").Value == "ServerManager"
                           select name.Element("User").Element("Permissions")
                           .Element("Permission").Attribute("Dir").Value;

因此,在这种情况下,我需要为特定用户添加另一个目录,该目录将不断变化。 很多情况下,我需要创建一个全新的用户。 预先感谢您的任何帮助。

好吧,在查看示例和给出的答案之后,我想我已经越来越近了。 但是,我仍然收到“父项丢失”异常或“对象引用”错误。 这是我用来尝试插入的以下代码。

            try
        {

            XDocument doc = XDocument.Load("C:/users/vildez/desktop/test.xml");

            XElement test = new XElement("TEST", "this is data");

            var InsertPoint = from user in doc.Descendants("Users")
                              where user.Element("User").Attribute("Name").Value == "ServerManager"
                              select user.Element("User").Element("Permissions").Element("Permission").Name;

            foreach (var v in InsertPoint)
            {
                XElement Perm = doc.Element(v.ToString());
                Perm.AddAfterSelf(test);
            }

            doc.Save("C:/users/vildez/desktop/123.xml");
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            Application.Exit();
        }

如果您尝试添加新的权限元素,则可以使用AddAfterSelf(请参阅: http : //msdn.microsoft.com/query/dev11.query? appId=Dev11IDEF1&l=EN-US&k=k(System.Xml.Linq.XNode .AddAfterSelf); k(AddAfterSelf); k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5); k(DevLang-csharp)&rd = true )。 您的Linq必须进行更改以删除.Attribute(“ Dir”)。Value

如果尝试添加第二个“ Dir”属性,则不能这样做。 XML属性应该是唯一的。

-回应评论-

“ ...我不是在尝试创建另一个属性,而是创建另一个元素,它将基本上克隆之前的那个属性以及只是不同的目录路径等”

听起来您想添加具有修改后的目录属性的其他Permission元素。

var InsHere = from name in doc.Descendants("Users")
              where name.Element("User").Attribute("Name").Value == "ServerManager"
              select name.Element("User").Element("Permissions").Element("Permission");
var newElement = new XElement(InsHere); // this clones the found Permission element
newElement.Attribute("Dir").Value = "the new directory path to add";
InsHere.AddAfterSelf(newElement);

看看是否满足您的要求。

只需系统地考虑一下即可。 将xml元素添加到文档中的特定xml元素需要做什么?

  1. 找到要添加到的xml元素。
  2. 获取/创建要添加的xml元素。
  3. 添加xml元素。

那么,在本文档中这意味着什么呢?

  1. 查找您要添加到的用户。 如果找到:
  2. 创建新的权限。
  3. 将新权限添加到用户的Permissions元素。
public XElement AddDirectoryPermissionForUser(XDocument doc, string userName, string dir)
{
    // I prefer using xpath queries over full linq queries
    var xpath = String.Format("//User[@Name='{0}']", userName);
    var user = doc.XPathSelectElement(xpath); // 1
    if (user != null)
    {
        var permission = CreatePermissionForDir(dir); // 2
        user.Element("Permissions").Add(permission); // 3
        return permission;
    }
    return null;
}

我不确定您到底在做什么,但这应该为您提供一个良好的起点。

您可以任何其他XElement 之前,之后添加XElement。

基于您的查询添加/调整选项的演示:

string userName = "ServerManager";
string directory = "some directory";
string optionName = "FileRead";
int optionSetting = 1;

XElement doc = XElement.Load("C:/users/vildez/desktop/test.xml");

XElement user = doc.Descendants("User")
                   .FirstOrDefault(user => 
                      user.Attribute("Name").Value == userName);

// Add user if it doesn't exist
if (user == null)
{
    XElement users = doc.Element("Users");
    if (users == null)
        doc.Add(users = new XElement("Users"));
    users.Add(user = new XElement("User",
        new XAttribute("Name", userName)));
}

XElement permission = user.Descendants("Permission")
                          .FirstOrDefault(perm => 
                          perm.Attribute("Dir").Value == directory);

// Add permission if it doesn't exist
if (permission == null)
{
    XElement permissions = user.Element("Permissions");
    if (permissions == null)
        user.Add(permissions = new XElement("Permissions"));
    permissions.Add(permission = new XElement("Permission",
        new XAttribute("Dir", directory)));
}
XElement option = permission.Elements("Option")
        .FirstOrDefault(op => op.Attribute("Name").Value == optionName);

// Add option if it doesn't exist
if (option == null)
    permission.Add(option = new XElement("Option", 
             new XAttribute("Name", optionName)));

option.Value = optionSetting.ToString();

我不太清楚您要完成的工作,但是以上内容将为Permission添加一个新的Option,并且如果Permission不存在,请添加它。

我只对根节点使用XElement(而不是XDocument),所以我将其更改为那个(XElement)。 上面的代码可能与使用XDocument一样工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM