简体   繁体   English

使用XDocument通过特定名称更改值

[英]Change a value by specific name using XDocument

I have a config file that I want to change certain key value pairs depending on user input. 我有一个配置文件,我想根据用户输入更改某些键值对。

Example of xml file is xml文件的示例是

<appSettings>
  <add key="key1"
       value="value1" />
  <add key="key2"
       value="value2" />
 </appSettings>

The user inputs a value for value 2 so I want to find key2 and update the value associated with it. 用户为值2输入一个值,因此我想找到key2并更新与之关联的值。

<appSettings>
  <add key="key1"
       value="value1" />
  <add key="key2"
       value="newValue" />
 </appSettings>

I have been trying to use this solution get key value pairs from xml using linq but cant figure out how to change the value. 我一直在尝试使用此解决方案使用linq从xml中获取键值对,但无法弄清楚如何更改值。 I don't think i need to parse either.. 我也不认为我也需要解析。

 public void changeAuthPolicyStoreAppName(string newPolicyStore, XDocument AppStore, string FOPath)
    {
        var newelement = new XAttribute("value", newPolicyStore);
        var changefoo = AppStore
                    .Descendants("add")
                    .Where(appSettings => appSettings.Attribute("key").Value == "key2")
                    .SingleOrDefault();
        changefoo.Attribute("value").Value = newPolicyStore;
        AppStore.Save(FOPath);
    }

Ok worked out the kinks this does what I am looking for. 确定解决了这个问题,正是我想要的。 Any improvements? 有什么改善吗?

You can use XPathSelectElement to find elements with specific names and/or attribute values: 您可以使用XPathSelectElement查找具有特定名称和/或属性值的元素:

    static void ModifyKeyValue(XDocument doc, int keyNumber, string newValue)
    {
        // XML fragment shows no namespace.  If your outer XML has a namespace, replace "string.Empty" with it.
        var namespaceManager = new XmlNamespaceManager(new NameTable());
        namespaceManager.AddNamespace("ns", string.Empty);

        // Select XElement named "appSettings" in default namespace
        var appSettings = doc.XPathSelectElement("//ns:appSettings", namespaceManager);
        if (appSettings == null)
            throw new InvalidOperationException(); // or create it?

        string keyValue = "key" + XmlConvert.ToString(keyNumber);
        string query = "./ns:add[@key='" + keyValue + "']";

        // Select elements named "add" with attribute "key" named "keyValue".
        var elements = appSettings.XPathSelectElements(query, namespaceManager).ToList();
        XElement element;
        if (elements.Count == 0)
        {
            // No element found with this key.  Add it.
            element = new XElement("add", new XAttribute("key", keyValue));
            appSettings.Add(element);
        }
        else if (elements.Count == 1)
        {
            element = elements[0];
        }
        else
        {
            throw new InvalidOperationException();
        }

        var attr = element.Attribute("value");
        if (attr == null)
            element.Add(new XAttribute("value", newValue));
        else
            attr.Value = newValue;
    }

And here's a version using only Linq-to-XML. 这是仅使用Linq-to-XML的版本。 Not sure it's that much simpler. 不知道这是否简单得多。

    static void ModifyKeyValue(XDocument doc, int keyNumber, string newValue)
    {
        // XML fragment shows no namespace.  If your outer XML has a default namespace, replace "string.Empty" with it.
        var nameSpace = string.Empty;

        // Select XElement named "appSettings" in namespace "nameSpace".
        var appSettings = doc.Descendants(XName.Get("appSettings", nameSpace)).SingleOrDefault();
        if (appSettings == null)
            throw new InvalidOperationException(); // or create it?

        string keyValue = "key" + XmlConvert.ToString(keyNumber);

        // Select sub-elements of "appSettings" named "add" with attribute "key" named "keyValue".
        var elements = appSettings.Elements(XName.Get("add", nameSpace)).Where(e => e.Attributes("key").Where(a => a.Value == keyValue).Any()).ToList();

        XElement element;
        if (elements.Count == 0)
        {
            // No element found with this key.  Add it.
            element = new XElement("add", new XAttribute("key", keyValue));
            appSettings.Add(element);
        }
        else if (elements.Count == 1)
        {
            element = elements[0];
        }
        else
        {
            throw new InvalidOperationException();
        }

        var attr = element.Attribute("value");
        if (attr == null)
            element.Add(new XAttribute("value", newValue));
        else
            attr.Value = newValue;
    }

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

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