Linq2XML separate keys into List - c#

I want to read a config.xml and put each item into a combobox so that the XML file is the datasource. This is my code, which only gives me one entry in my combobox. How do I separate the keys? This is my filter:
C#
var xmlDocument = XDocument.Load(configfile);
var anredeItems = from key in xmlDocument.Descendants("Anrede")
select key.Value.Trim();
anredeNrComboBox.DataSource = anredeItems.ToList();
This is the XML:
<?xml version="1.0"?>
<Config>
<Anrede>
<key_1>Herrn</key_1>
<key_2>Frau</key_2>
<key_3>Herrn Dr.</key_3>
<key_4>Frau Dr.</key_4>
<key_5>Herrn Dr. Med.</key_5>
</Anrede>
</Config>

Your Descendants("Anrede") query will get you the element Andrede, and reading the Value property of that will return the concatenation of all descendant text nodes, which is what you are seeing in your combo box.
What you want are each of its child element values:
var items - doc.Descendants("Anrede")
.Elements()
.Select(x => x.Value.Trim())
.ToList();

You can change your code like this:
var xmlDocument = XDocument.Load(configfile);
var anredeItems = xmlDocument.Root.Elements("Anrede").Elements().Select(p => p.Value.Trim());
anredeNrComboBox.DataSource = anredeItems.ToList();

Related

XML Select Node into List Fail

No problems loading a simple XML file into a LIST. BUT, when I create a second element it loads, but loads everything into one line.
I have even tried using xmlDoc.Descendants("apple") with the same results.
Works.
<?xml version="1.0" encoding="utf-8"?>
<green_apple>
<Location>CA</Location>
<Price>.52</Price>
</green_apple>
XDocument xmlDoc = XDocument.Load("apple.xml");
List<string> list = xmlDoc.Root.Elements()
.Select(element => element.Value.Trim())
.ToList();
List Result:
list[0] = CA
List[1] = .52
Doesn't Work.
<?xml version="1.0" encoding="utf-8"?>
<apple>
<green_apple>
<Location>CA</Location>
<Price>.52</Price>
</green_apple>
<red_apple>
<Location>FL</Location>
<Price>.71</Price>
</red_apple>
</apple>
XDocument xmlDoc = XDocument.Load("apple.xml");
List<string> list = xmlDoc.Root.Elements("green_apple") <<specify specify element.
.Select(element => element.Value.Trim())
.ToList();
List Result:
list[0] = CA.52 <<Here's the problem, they should be in their own list element.
Elements retuns child elements of the current node, which in your case are green_apple elements. So you need to get green_apple child nodes by calling Elements() on green_apple element.
Use this:
List<string> list = xmlDoc.Root.Elements("green_apple").Elements()
.Select(element => element.Value.Trim())
.ToList();

C# Read a specific element which is in a XML Node

I searched a long time in order to get an answer but as i can see is not working.
I have an XML File and I would like to read a specific element from a node.
For example, this is the XML:
<Root>
<TV>
<ID>2</ID>
<Company>Samsung</Company>
<Series>13523dffvc</Series>
<Dimesions>108</Dimesions>
<Type>LED</Type>
<SmartTV>Yes</SmartTV>
<OS>WebOS</OS>
<Price>1993</Price>
</TV>
</Root>
I want to get the ID element in the code as a variable so i can increment it for the next item which i will add.
This is the code at this moment, but i can not find a way to select something from the item itself.
XDocument doc = XDocument.Load("C:TVList.XML");
XElement TV = doc.Root;
var lastElement = TV.Elements("TV").Last()
A query for the last TV's id (this will return 0 if there are no elements):
var lastId = (int) doc.Descendants("TV")
.Elements("ID")
.LastOrDefault();
You might also want the highest id (in case they're not in order):
var maxId = doc.Descendants("TV")
.Select(x => (int)x.Element("ID"))
.DefaultIfEmpty(0)
.Max();
See this fiddle for a working demo.
Use like this to get id value
XDocument doc = XDocument.Load(#"C:\TVList.XML");
XElement root = doc.Element("Root");
XElement tv = root.Element("TV");
XElement id = tv.Element("ID");
string idvalue = id.Value;
also make your <Type>LED</Tip> tag of xml to <Type>LED</Type> for match

Use LINQ XML with a namespace

I am trying to find nodes in an XML document like this:
<?xml version="1.0"?>
<TrainingCenterDatabase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
<Activities>
<Activity Sport="CyclingTransport">
<Id>2014-07-08T15:28:14Z</Id>
</Activity>
</Activities>
</TrainingCenterDatabase>
I aim to extract the node value 'Id' with code like this:
XDocument doc = XDocument.Load(filePath);
List<string> urlList = doc.Root.Descendants("Id")
.Select(x => (string)x)
.ToList();
Console.WriteLine(urlList.Count);
However the count is 0, where I expect 1.
After some debugging and editing the XML I noticed that if I change the TrainingCenterDatabase node and remove the attributes to this:
<TrainingCenterDatabase>
Then the result is a count of 1 as expected.
So my question is how do I take into account the namespaces so that I can get the value when the TrainingCenterDatabase node has these attributes?
Namespaces in XML can be tricky. I've run into this problem myself a number of times. In all likelihood, the following will fix your problem:
XDocument doc = XDocument.Load(filePath);
List<string> urlList = doc.Root.Descendants(doc.Root.Name.Namespace.GetName("Id"))
.Select(x => (string)x)
.ToList();
Console.WriteLine(urlList.Count);
Basically, this just assumes the underlying element to have the same namespace as your root element. That's true in this case, but of course it doesn't have to be.
The right way, probably, is to do it explicitly. Now, granted, that kind of depends on how you're using this and your datasource, so make the decision for yourself, but that would require doing something more like this:
XDocument doc = XDocument.Load(filePath);
List<string> urlList = doc.Root.Descendants(System.Xml.Linq.XName.Get("Id", "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"))
.Select(x => (string)x)
.ToList();
Console.WriteLine(urlList.Count);
The cause for your problem was that the default behavior for XElement, when not given an explicit namespace, is to assume no namespace. However, the default behavior for the XML spec is to assume the parent's namespace. In your case, those two were different, so it wasn't able to find the descendant.
It Works...
XDocument doc = XDocument.Load(filePath);
XNamespace ns = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2";
var root = doc.Descendants(ns + "Id").Select(x => x.Value).ToList();
Console.WriteLine(root.Count);

How do I parse text from complex type xml in c# using XDocument?

<?xml version="1.0" encoding="UTF-8"?>
<meta>
<field type="xs-string" name="AssetId">TF00000002</field>
<field type="xs-string" name="Title">TitleOfAsset</field>
</meta>
I have this XML loaded in to a XDocument using the function
XDocument doc = XDocument.Parse(xmlData)
However, I want to be able to retrieve the text fields "TF00000002" and "TitleOfAsset" ... How do I go about doing this?
templateMetaData.assetID = doc
.Descendants()
.Where(p => p.Name.LocalName == "AssetId")
.ToString();
returns:
System.Linq.Enumerable+WhereEnumerableIterator`1[System.Xml.Linq.XElement]
Can anyone shine a light on this?
In your query, you are calling ToString on an IEnumerable<XElement> which will never give you the expected result, instead look for field elements under your Root and get their value:
var values = doc.Root
.Elements("field")
.Select(element => (string)element);
If you want to access your values using the name attribute you can use Dictionary:
var values = doc.Root
.Elements("field")
.ToDictionary(x => (string)x.Attribute("name"), x => (string)x);
Then you can access the value of AssetId:
var id = values["AssetId"];

How to access the properties on a XML Node via linq?

I read through this post.
I have this XML:
<?xml version="1.0" encoding="utf-8" ?>
<Export version="" srcSys="" dstSys="" srcDatabase="" timeStamp="">
</Export>
This is what i tried, but with no luck:
var xml = XElement.Parse(BuyingModule.Properties.Resources.Export);
Func<XElement, string, string> GetAttribute = (e, property) => e.Elements("property").Where(p => p.Attribute("name").Value == property).Single().Value;
var query = from record in xml.Elements("Export")
select record;
var prop = GetAttribute(query.FirstOrDefault(), "version");
How do i access to properties of the "Export" Node?
I need to set those properties
The Export element doesn't have a properties element, which is what your GetAttribute method is trying to find.
My guess is you actually want:
var element = xml.Element("Export"); // Just get the first element
var version = (string) element.Attribute("version");
It's not clear to me why you've used a query expression and a delegate here - it's just things more complicated than you need. But Attribute(XName) is probably what you were missing...

Categories

Resources