views:

532

answers:

3

I have this XML in a column in my table:

<keywords>
  <keyword name="First Name" value="|FIRSTNAME|" display="Jack" />
  <keyword name="Last Name" value="|LASTNAME|" display="Jones" />
  <keyword name="City" value="|CITY|" display="Anytown" />
  <keyword name="State" value="|STATE|" display="MD" />
</keywords>

I'm getting a record out of that table using LINQ to SQL via this:

GeneratedArticle ga = db.GeneratedArticles.Single(p => p.GeneratedArticleId == generatedArticleId);

That works, I get my GeneratedArticle object just fine.

I'd like to walk through the data in the ArticleKeywords field, which is XML. I started doing this:

var keywords = from k in ga.ArticleKeywords.Elements("Keywords")
                    select k;

            foreach (var keyword in keywords)
            {
             //what goes here?   
            }

I'm not 100% sure that I'm getting that data correctly. I need help with the proper syntax to get the value and display out of my XML field.

A: 

I would think something like this would work

var keywordData = from k in ga.ArticleKeywords.Elements("Keywords")
                  select new { Value = k.Attributes["value"].Value,
                               Display = k.Attributes["display"].Value};

This would give you an IEnumerable of an anonymous type containing a Value and a Display property. Depending on what your doing you could easily replace the anonymous type with a concrete type.

ckramer
k.Attributes["something"] won't compile
aku
ga.ArticleKeywords.Elements("Keywords") - doesn't return keywords
aku
+2  A: 

Here is a sample code:

To read keywords we need to call Elements("keyword") not Elements("keywords") since keywords is a root node.

// IEnumerable sequence with keywords data
var keywords = from kw in ga.ArticleKeywords.Elements("keyword")
               select new {
                   Name = (string)kw.Attribute("name"),
                   Value = (string)kw.Attribute("value"),
                   Display = (string)kw.Attribute("display")
               };


foreach (var keyword in keywords)
{
    var kw = "Name: " + keyword.Name + 
             " Value: " + keyword.Value + 
             " Display: " + keyword.Display;
    Console.WriteLine(kw);
}

You can get attribute value using foo.Attribute("bar").Value, but this method would throw exception if attribute is missing. Safe way to get attribute value is (string)foo.Attribute("bar") - it will give you null if attribute is missing

aku
+3  A: 

Once again I am amazed that people don't even try their answers and people still up vote when they don't work. The .Elements will get the list of elements at the current root, which is not a keyword.

Also the one using .Attributes["X"] does not even compile you need to use () of course again it would be operating on each instance of "keywords" not "keyword"

You could use

var keywords = from kw in ga.ArticleKeywords.Element("keywords").Elements()

or

var keywords = from kw in ga.ArticleKeywords.Element("keywords").Elements("keyword")

or (this will get all the keyword elements regardless of level)

var keywords = from kw in ga.ArticleKeywords.Descendants("keyword")