使用XDocument按特定名称更改值

时间:2015-02-06 17:59:04

标签: c# asp.net xml linq-to-xml

我有一个配置文件,我想根据用户输入更改某些键值对。

xml文件的示例是

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

用户输入值2的值,因此我想找到key2并更新与之关联的值。

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

我一直在尝试使用此解决方案get key value pairs from xml using linq,但无法弄清楚如何更改该值。我认为我不需要解析..

 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);
    }

好的解决了我正在寻找的问题。有什么改进吗?

1 个答案:

答案 0 :(得分:0)

您可以使用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;
    }

这是一个只使用Linq-to-XML的版本。不确定它更简单。

    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;
    }