I have a simple program that would let the user add a section to a custom config file, it would have more settings than what is shown. I populate a datagridview with a list of all configurations. My problem is, the method to populate the listbox wouldn't know all the names of the sections that the user may have added, I'm trying to be dynamic. Is there an easy way to loop through these sections and get their names? Or do I have to make a Section, Collection, and Elements in order to to this?
Thanks.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="Jason" type="SQLQueryOutput.SQLQueryOutputConfigSection, SQLQueryOutput, Version=1.0.0.0, Culture=neutral, PublicKeyToken=760d257b40400289" />
<section name="Steve" type="SQLQueryOutput.SQLQueryOutputConfigSection, SQLQueryOutput, Version=1.0.0.0, Culture=neutral, PublicKeyToken=760d257b40400289" />
</configSections>
<Jason OutputFilePath="C:\temp\jason.txt" />
<Steve OutputFilePath="C:\temp\steve.txt" />
</configuration>
How about using Linq To Xml to parse your config file. For example,
var xDoc = XDocument.Load(configFile);
var sections = xDoc.XPathSelectElements("//configSections/section")
.Select(x=>x.Attributes().ToDictionary(a=>a.Name,a=>a.Value))
.ToList();
var name = sections[0]["name"];
or
var outputFilePaths = xDoc.Root.Elements()
.Where(d => d.Name.LocalName != "configSections")
.ToDictionary(e => e.Name.LocalName, e => e.Attribute("OutputFilePath").Value);
Actually your configSections element can contain sectionGroup elements also. With Linq to Xml:
XDocument xdoc = XDocument.Load(config_file_path);
var names = xdoc.Root.Element("configSections")
.Descendants("section") // selects also sectionGroup/section
.Select(s => (string)s.Attribute("name"));
Related
I have this xml file:
<Assemblies>
<Assembly Name="MyMainAssambly.exe" Version="1.7.0.0" Path="x:\MyMainAssemby.exe" >
<NeededAssemblies>
<Assembly Name="Aseembly01.dll" Version="1.1.1.1" Path="x:\Assembly01.dll"/>
<Assembly Name="Aseembly02.dll" Version="2.2.2.2" Path="x:\Assembly02.dll"/>
<Assembly Name="Aseembly03.dll" Version="3.3.3.3" Path="x:\Assembly03.dll"/>
</NeededAssemblies>
</Assembly>
</Assemblies>
I want to iterate all of them to do some tasks. So I am trying to use this code:
XElement myMainAssembly = miDocumentoXml.Root.Elements("Assembly")
.Where(x => x.Attribute("Name").Value == "MyMainAssembly.exe"
&& x.Attribute("Version").Value.StartsWith("1.7.0.0"))
.FirstOrDefault();
foreach (XElement nodeIterator in myMainAssembly.DescendantNodesAndSelf())
{
//Do some code with the nodes Assembly01.dll, Assembly02.dll and Assembly, using the name, version and path.
string miStrAssemblyName = nodeIterator .Attribute("Name").Value;
}
But if I debbug and set a break point, I can see that the property HasAttributes of all elements is false. Why? Because in the xml all the elements have 3 attriibutes. In fact, in the first part of code, where I get my main assembly, I can use Attribute("Name") to get the name of the main assembly. But later in the foreach I can't.
So I would like to know how to iterate the elements and get the information of the attributes.
Thanks.
Hi i have the following app.config file
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="DayTime" value="08-20" />
<add key="NightTime" value="20-08" />
<add key="ClientSettingsProvider.ServiceUri" value="" />
<add key="GridMode" value="1"/>
</appSettings>
I need to read all the keys at one shot and store it some where like Dictionary.
I have tried following code but give me null value
with exception Cannot convert Keyvalueinternalcollection to hashtable
var section = ConfigurationManager.GetSection("appSettings") as Hashtable;
How to read all keys with their values ?
Hashtable version.
Hashtable table = new Hashtable((from key in System.Configuration.ConfigurationManager.AppSettings.Keys.Cast<string>()
let value= System.Configuration.ConfigurationManager.AppSettings[key]
select new { key, value }).ToDictionary(x => x.key, x => x.value));
Comment to other answers
System.Configuration.ConfigurationManager.AppSettings is predefined 'appSettings' section, use it.
Do not cast to Hashtable but to IEnumerable instead:
var section = ConfigurationManager.GetSection("appSettings");
foreach (var kvp in section as IEnumerable)
{
//TODO
}
I think you can do something like this:
var loc=(NameValueCollection)ConfigurationSettings.GetSection("appSettings");
var dic=new Dictionary<string,string>();
foreach (var element in loc.AllKeys)
{
dic.Add(element, loc[k]);
}
var section = ConfigurationManager.GetSection("appSettings")
should suffice.
I have an XML file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="publisher" type="KP.Common.Util.XamlConfigurationSection, KP.Common"/>
</configSections>
<publisher>
<p:Publisher xmlns:p="http://schemas.KP.com/xaml/common/notification">
<p:KPLogSubscriber MinimumImportance="Information" />
<p:EventLogSubscriber MinimumImportance="Warning" Source="KPTTY" Log="Application" />
<p:DatabaseMailSubscriber xmlns="http://schemas.KP.com/xaml/data/ef" MinimumImportance="Error" ProfileName = "" Recipients = "administrator#firm.com" Subject = "KPTTY Error" />
</p:Publisher>
</publisher>
</configuration>
I am trying to read the value of the key Recipients using this code:
XmlDocument config = new XmlDocument();
config.Load(configPath);
XmlNode node = config.SelectSingleNode(#"/*[local-name() = 'configuration']/*[local-name() = 'publisher']/*[local-name() = 'Publisher']/*[local-name() = 'DatabaseMailSubscriber']/#Recipients");
Console.WriteLine(node.Value);
but I get an exception (node is null). Is there something wrong with my Xpath? I am trying to ignore any namespaces that might not be present in the xml.
If it is OK to use Linq2Xml
XDocument xDoc = XDocument.Load(fname);
var recipients = xDoc.Descendants()
.First(d => d.Name.LocalName == "DatabaseMailSubscriber")
.Attribute("Recipients")
.Value;
You forgot to do local-name for "Recipients". "Recipients" attribute have empty prefix meaning its namespace is xmlns="http://schemas.KP.com/xaml/data/ef" as defined on the "DatabaseMailSubscriber" element.
I.e. if you don't care of path you can simple use "//" for "any child:
"//*[local-name() = 'DatabaseMailSubscriber']/#*[local-name() = 'Recipients]"
Note: consider actually using namespace properly... or use XDocument as suggested by L.B.
I have this app.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="domain" value="localhost"/>
<add key="hostname" value="hostpc"/>
</appSettings>
</configuration>
I am using this LINQ to XML query to get the value of key named "domain". For instance, when i say i want to get value of key named "domain" it should give me "localhost" :
var domain = (from appNode in xmlElement.Elements("add")
where appNode.Attribute("key").Value == "domain"
select appNode.Attribute("value"));
But my query is missing something can anyone identify what i am missing or how it can be made better, it doesn't work at the moment.
Note: I only want to use linq to xml
I used your app.config file content as it is, write a small console based application with following code:
class Program
{
static void Main(string[] args)
{
// Create the query
var nodes = from appNode in XElement.Load("App.config").Descendants("appSettings").Elements()
where appNode.Attribute("key").Value == "domain"
select appNode;
var element = nodes.FirstOrDefault();
string value = element.Attribute("value").Value;
Console.WriteLine(value);
//Pause the application
Console.ReadLine();
}
}
The output is: localhost
Hope this helps. If it does not work on your machine, please share error details.
try using this one:
XElement doc = XElement.Load("ConsoleApplication1.exe.config");
var domain = (from appNode in doc.Element("appSettings").Elements("add")
where appNode.Attribute("key").Value == "domain"
select appNode.Attribute("value").Value).FirstOrDefault();
I am developing asp.net mobile application. I am using the XML as a database. I am using the following part of the XML file to query the data by using the LINQ to XML.
<USER-INTERFACE-DEFINITION>
<MIMICS>
<MIMIC ID="1" NAME="Home">
<SECTIONS>
<SECTION ID ="1" NAME="System Health" CONTROL-TYPE="Button">
<DATAITEMS>
</DATAITEMS>
</SECTION>
<SECTION ID ="2" NAME="Network Status" CONTROL-TYPE="Button">
<DATAITEMS>
</DATAITEMS>
</SECTION>
<SECTION ID ="3" NAME="ESD Status" CONTROL-TYPE="Button">
<DATAITEMS>
</DATAITEMS>
</SECTION>
<SECTION ID ="4" NAME="DWPLEM" CONTROL-TYPE="Button">
<DATAITEMS>
</DATAITEMS>
</SECTION>
<SECTION ID="5" NAME="Manifolds" CONTROL-TYPE="Drowpdown">
<DATAITEMS>
</DATAITEMS>
</SECTION>
<SECTION ID ="6" NAME="Wells" CONTROL-TYPE="Drowpdown">
<DATAITEMS>
</DATAITEMS>
</SECTION>
<SECTION ID ="7" NAME="Alarms" CONTROL-TYPE="Button">
<DATAITEMS>
</DATAITEMS>
</SECTION>
<SECTION ID ="8" NAME="House Keeping" CONTROL-TYPE="Button">
<DATAITEMS>
</DATAITEMS>
</SECTION>
</SECTIONS>
</MIMIC>
</USER-INTERFACE-DEFINITION>
In the above XML file I want to retrive the "NAME" attribute of the SECTION node with the condition MIMIC ID="1". I dont want to modify my existing XML file. I have the server collection of node with simialr elements as the above XML file. Can you please provide me any code or link through which I can resolve the above issue ?
var xml = XElement.Parse("your xml");
var q = from m in xml.Descendants("MIMIC")
where (int)m.Attribute("ID") == 1
from s in m.Descendants("SECTION")
select (string)s.Attribute("NAME");
foreach ( var name in q ) {
Console.WriteLine(name);
}
I have tested the above in LINQPad and it does indeed produce:
System Health
Network Status
ESD Status
DWPLEM
Manifolds
Wells
Alarms
House Keeping
Perhaps something like (not LINQ, but you can use it with LINQ if you like):
var nodes = myXmlDoc.SelectNodes("/USER-INTERFACE-DEFINITION/MIMICS/MIMIC[#ID='1']/SECTION/#NAME");
foreach(var node in nodes)
{
string name = node.Value;
// do something with each name
}
(assuming myXmlDoc is created using .Load(yourXmlFileHer) and assuming USER-INTERFACE-DEFINITION is the root of the XML, otherwise, start with // instead)
Assuming your XML is held in a string called xml then:
var root = XElement.Parse(xml);
var results = root
.Descendants("MIMIC")
.Where( e => e.Attribute("ID").Value == "1" )
.SelectMany(e => e.Descendants("SECTION").Attributes("NAME" ) ) ;
I'll give it my best try but you might wan't to supply the relevant part of the XML to make it easier for us. Does the section have this condition or the name. At least I might get you started.
Let's start with this:
var name = xml.Descendants<SECTION>.Where(s => s.id == 1).GetFirstChild<NAME>();
Hoping I'm not way off, if that's the case I guess someone will suply a better answer.
Ok after seeing your XML I was some way off. Also when I think about it Descendants probably woudln't work.