[英]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.