 | | | Join Date: Sep 2009 Location: Usa, Michigan, Westland
Posts: 146
| |
Due to a recent suggestion...
And after failing to make a simple program to play with the code and see what it does... I come bearing questions, and seeking help...
Console App - using System;
-
using System.Collections.Generic;
-
using System.Linq;
-
using System.Xml;
-
using System.Xml.Linq;
-
using System.Text;
-
-
namespace ConsoleApplication1
-
{
-
class Program
-
{
-
static void Main(string[] args)
-
{
-
var xdata = from d in XElement.Load("dk.xml").Elements("Talent")
-
select d;
-
-
foreach (var data in xdata)
-
{
-
Console.WriteLine(data);
-
}
-
Console.ReadLine();
-
}
-
}
-
}
Program compiles. All the console window does is the ReadLine() method, it doesn't show any data at all. can anyone tell me why I'm not getting any output?
|  | | | Join Date: Mar 2008 Location: Arizona, USA
Posts: 3,476
| | | re: Readng XML via LINQ
Just guessing that the path "dk.xml" does not lead to a file.
I think the default search is to check in the same folder as the executable.
Perhaps testing with the file a known valid location like "C:\\dk.xml"
|  | | | Join Date: Sep 2009 Location: Usa, Michigan, Westland
Posts: 146
| | | re: Readng XML via LINQ
Thanks for the quick response.
I tried putting the XML file in the C:/ . Same result.
I tried using Console.Write instead.
I tried using data.ToString().
All the "Talent" tags in my XML file with don't have a closing tag (The syntax is w3 compliant though). So I tried to read a tag with a closing tag... Still no go...
Just figured I would try and see if it did anything. Though it didn't seem to work. =\
|  | | | Join Date: Apr 2008 Location: San Antonio, TX (USA)
Posts: 2,839
| | | re: Readng XML via LINQ
I've been meaning to do a writeup of this eventually, but I haven't had time. I'll do a quick condensed version here for you to get started. I really love LINQ and want everyone to start using it =D
First, make sure to add a reference to System.Xml.Linq if you haven't, and make sure it's in your using statements. (I see that you already have, but I'm putting this here for other people's benefit).
The first part of the following code gets all the descendant nodes of the root element in the XML document, then loops through them and prints their values. I used the standard long notation for this.
The second part shows a query to find a specific string in the xml, namely the value of the first descendant node called "body". I used shorthand and a lambda expression for this example.
Here's a sample that can get you started. C# Program - using System;
-
using System.Linq;
-
using System.Xml.Linq;
-
-
namespace TermsHelper
-
{
-
class Program
-
{
-
static void Main(string[] args)
-
{
-
XDocument doc = XDocument.Load(@"c:\dev\temp.xml");
-
-
//standard notation
-
var data = from x in doc.Root.Descendants()
-
select x;
-
foreach (XElement e in data)
-
Console.WriteLine(e.Value);
-
-
//alternate notation
-
string body = doc.Root.Descendants().Where(x => x.Name == "body").First().Value;
-
-
Console.WriteLine("\nBody: {0}", body);
-
-
//attribute example
-
string attribute = doc.Root.Descendants().Where(x => x.Name == "body").First().Attribute("type").Value;
-
Console.WriteLine("\nAttribute: {0}", attribute);
-
Console.Read();
-
}
-
}
-
}
temp.xml - <?xml version="1.0"?>
-
<note>
-
<to>Tove</to>
-
<from>Jani</from>
-
<heading>Reminder</heading>
-
<body type="text">Don't forget me this weekend!</body>
-
</note>
Expected output when executed - Tove
-
Jani
-
Reminder
-
Don't forget me this weekend!
-
-
Body: Don't forget me this weekend!
-
-
Attribute: text
Good luck.
|  | | | Join Date: Sep 2009 Location: Usa, Michigan, Westland
Posts: 146
| | | re: Readng XML via LINQ
Don't suppose I could get a quickie example pertaining to attributes?
|  | | | Join Date: Apr 2008 Location: San Antonio, TX (USA)
Posts: 2,839
| | | re: Readng XML via LINQ
Sure, I'll edit my original post to include an attribute example. Attribute("name") is a method of XElement that returns the first XAttribute of the XElement that matches the name. Attributes() will return a list.
|  | | | Join Date: Sep 2009 Location: Usa, Michigan, Westland
Posts: 146
| | | re: Readng XML via LINQ
Awesome. I believe I've got the hang of singular Linq'n here. lol
This is a quickie layout of my current XML file. - <base>
-
<tree1>
-
<tag1 />
-
...
-
<tag44 />
-
</tree1>
-
...
-
<tree3 />
-
</base>
-
So far I've wrote this: - var query = from x in xmldoc.Root.Descendants()
-
select (XElement)x.Element("Talent");
And when I console it. I get Tag1 from each of the 3 trees and then a $hit ton of White Space. And thats it... lol
What I want to do is basicly read each Tag into a List or Array. All the examples I can find half the time either just give me a single item return, or they create an XML which I will not be doing at all.
|  | | | Join Date: Apr 2008 Location: San Antonio, TX (USA)
Posts: 2,839
| | | re: Readng XML via LINQ
This would work better: - var query = from x in xmldoc.Root.Descendants().Elements("Talent")
-
select x;
Here's an example that uses your sample XML and does what you want in two different ways. The first way just gets all the elements who's name contains the string "tag". The second uses a custom data type and nested LINQ queries to give you a list of trees, with each tree containing a list of tags. - using System;
-
using System.Linq;
-
using System.Xml.Linq;
-
using System.Collections.Generic;
-
-
namespace TermsHelper
-
{
-
class Program
-
{
-
static void Main(string[] args)
-
{
-
XDocument doc = XDocument.Load(@"c:\dev\temp.xml");
-
-
//just tags
-
List<XElement> elements = (from x in doc.Root.Descendants()
-
where x.Name.LocalName.Contains("tag")
-
select x).ToList();
-
-
foreach (XElement e in elements)
-
Console.WriteLine(e.Name);
-
-
Console.WriteLine();
-
-
//custom data type, hierarchical
-
-
List<Tree> trees = (from x in doc.Root.Descendants()
-
where x.Name.LocalName.Contains("tree")
-
select new Tree
-
{
-
TreeName = x.Name.ToString(),
-
Tags = (from y in x.Elements()
-
where y.Name.LocalName.Contains("tag")
-
select y).ToList()
-
}).ToList();
-
-
foreach (Tree t in trees)
-
{
-
Console.WriteLine("Tree Name: {0}", t.TreeName);
-
Console.WriteLine("Tags:");
-
foreach (XElement e in t.Tags)
-
Console.WriteLine(e.Name);
-
Console.WriteLine();
-
}
-
-
Console.Read();
-
}
-
}
-
public class Tree
-
{
-
public string TreeName { get; set; }
-
public List<XElement> Tags { get; set; }
-
}
-
}
Contents of temp.xml - <?xml version="1.0"?>
-
<base>
-
<tree1>
-
<tag1 />
-
<tag2 />
-
<tag44 />
-
</tree1>
-
<tree2>
-
<tag1 />
-
</tree2>
-
<tree3 />
-
</base>
Expected Output -
tag1
-
tag2
-
tag44
-
tag1
-
-
Tree Name: tree1
-
Tags:
-
tag1
-
tag2
-
tag44
-
-
Tree Name: tree2
-
Tags:
-
tag1
-
-
Tree Name: tree3
-
Tags:
-
|  | | | Join Date: Sep 2009 Location: Usa, Michigan, Westland
Posts: 146
| | | re: Readng XML via LINQ
Well. Thanks for all the help! Though this LINQ stuff is a headache, and I doubt I'll be learning much more since just trying to figure out your examples, I couldn't really figure it out. Most tutorials out there do more XML generation rather then reading. Especially the MSDN examples... Ugh.
This is what I came up with... - XDocument xmldoc = XDocument.Load("dk.xml");
-
var query = from x in xmldoc.Root.Descendants()
-
where x.Name == "Talent"
-
select x;
-
foreach (XElement q in query)
-
{
-
Console.Write(q.Name + ": ");
-
Console.Write(q.Attribute("id").Value + ",");
-
if (Int32.Parse(q.Attribute("pts").Value) > 0)
-
{
-
Console.Write(q.Attribute("pts").Value + ",");
-
Console.Write(q.Attribute("title").Value + ",");
-
Console.Write(q.Attribute("icon").Value);
-
if (q.LastAttribute.Name == "req")
-
Console.Write("," + q.Attribute("req").Value);
-
}
-
else
-
{
-
Console.Write(q.Attribute("pts"));
-
}
-
Console.WriteLine("--");
Output is: - Tag: 1,5,title,icon
-
Tag: 2,0
-
... (132 total)
Each "Tag" output will be listed in its own List.
|  | | | Join Date: Sep 2009 Location: Usa, Michigan, Westland
Posts: 146
| | | re: Readng XML via LINQ
So ok. Now my next question... Using the above code... How would I get a sibling node ( if thats what its called? ) through the same loop?
Would I use another Decendant() call? - <talent>
-
<disc>
-
Some stuff here
-
</disc>
-
</talent>
|  | | | Join Date: Apr 2008 Location: San Antonio, TX (USA)
Posts: 2,839
| | | re: Readng XML via LINQ - q.Element["whatever"].Value
Should give you the value of the first child node named "whatever"
|  | | | Join Date: Sep 2009 Location: Usa, Michigan, Westland
Posts: 146
| | | re: Readng XML via LINQ
The " [] " brackets didn't work, but the " () " did. Thanks!
|  | | | Join Date: Apr 2008 Location: San Antonio, TX (USA)
Posts: 2,839
| | | re: Readng XML via LINQ
Oops, sorry, forgot it was a method and not an index.
|  | | | |