tags:

views:

455

answers:

5

I have several XML files that I wish to read attributes from. My main objective is to apply syntax highlighting to rich text box.

For example in one of my XML docs I have: <Keyword name="using">[..] All the files have the same element: Keyword.

So, how can I get the value for the attribute name and put them in a collection of strings for each XML file.

I am using Visual C# 2008.

+2  A: 

You could use XPath to get all the elements, then a LINQ query to get the values on all the name atttributes you find:

 XDocument doc = yourDocument;
 var nodes = from element in doc.XPathSelectElements("//Keyword")
             let att = element.Attribute("name")
             where att != null
             select att.Value;
 string[] names = nodes.ToArray();

The //Keyword XPath expression means, "all elements in the document, named "Keyword".

Edit: Just saw that you only want elements named Keyword. Updated the code sample.

driis
How do I give XDocument the value of my XML document? In Visual C#, on the solution explorer, I have a folder called APIs, inside are all the XML documents, for example: batch.xml. Do I instantiate it as a String or what?
Mohit Deshpande
@Mohit: `XDocument doc = XDocument.Load(@"API\batch.xml");` should do the trick
marc_s
Mohit Deshpande
Sorry that was my fault
Mohit Deshpande
A: 

You could use LINQ to XML.

Example:

var xmlFile = XDocument.Load(someFile);
var query = from item in xmlFile.Descendants("childobject")
            where !String.IsNullOrEmpty(item.Attribute("using")
            select new 
            {
                AttributeValue = item.Attribute("using").Value
            };
Joseph
A: 

You'll likely want to use XPath. //Keyword/@name should get you all of the keyword names.

Here's a good introduction: .Net and XML XPath Queries

Ryan Emerle
+4  A: 

The other answers will do the job - but the syntax highlighting thingy and the several xml files you say you have makes me thinks you need something faster, why not use a lean and mean XmlReader?

private string[] getNames(string fileName)
{

  XmlReader xmlReader = XmlReader.Create(fileName);
  List<string> names = new List<string>(); 

  while (xmlReader.Read())
  {
   //keep reading until we see your element
   if (xmlReader.Name.Equals("Keyword") && (xmlReader.NodeType == XmlNodeType.Element))
   {
     // get attribute from the Xml element here
     string name = xmlReader.GetAttribute("name");
     // --> now **add to collection** - or whatever
     names.Add(name);
   }
  }

  return names.ToArray();
}

Another good option would be the XPathNavigator class - which is faster than XmlDoc and you can use XPath.

Also I would suggest to go with this approach only IFF after you try with the straightforward options you're not happy with performance.

JohnIdol
That's exactly what I need but... how do I cast "whatever" as a String array?
Mohit Deshpande
For syntax highlighting, I very much doubt that he'll want to read the file over and over. The obvious solution is to read it *once*, which means that speed is much less important than readability. Using LINQ to XML is the obvious solution here, IMO.
Jon Skeet
@JonSkeet I agree - indeed I suggested to consider this approach only IF performance turns out to be an issue (for example - reading the file once - it might be the case that this needs to be performed over a large number of big files and startup/load performance could be significantly affected)
JohnIdol
@Mohit - I threw in a list of strings. if you need a string[] you should be able to call .ToArray() on the list.
JohnIdol
Thanks everyone but how do I syntax highlight in a RichTextBox? I will be putting this code in a method so how do I return names.ToArray()?
Mohit Deshpande
@Mohit 'return names.ToArray();'
JohnIdol
see answer - I added that code
JohnIdol
syntax highlight is a separate problem - I suggest you start another question just on that topic if you're looking for answers on that as well (it is not clear from the question)
JohnIdol
+2  A: 

Like others, I would suggest using LINQ to XML - but I don't think there's much need to use XPath here. Here's a simple method to return all the keyword names within a file:

static IEnumerable<string> GetKeywordNames(string file)
{
    return XDocument.Load(file)
                    .Descendants("Keyword")
                    .Attributes("name")
                    .Select(attr => attr.Value);
}

Nice and declarative :)

Note that if you're going to want to use the result more than once, you should call ToList() or ToArray() on it, otherwise it'll reload the file each time. Of course you could change the method to return List<string> or string[] by -adding the relevant call to the end of the chain of method calls, e.g.

static List<string> GetKeywordNames(string file)
{
    return XDocument.Load(file)
                    .Descendants("Keyword")
                    .Attributes("name")
                    .Select(attr => attr.Value)
                    .ToList();
}

Also note that this just gives you the names - I would have expected you to want the other details of the elements, in which case you'd probably want something slightly different. If it turns out you need more, please let us know.

Jon Skeet