10

I have XML String:

   <GroupBy Collapse=\"TRUE\" GroupLimit=\"30\">
      <FieldRef Name=\"Department\" />
   </GroupBy>
   <OrderBy>
      <FieldRef Name=\"Width\" />
   </OrderBy>

I am new in C#. I tried to read the Name attribute of the FieldRef element for both elements but I could not. I used XMLElement , is there any way to pick these two values?

Waleed
  • 175
  • 2
  • 2
  • 10

2 Answers2

12

Despite the posting of invalid XML (no root node), an easy way to iterate through the <FieldRef> elements is to use the XmlReader.ReadToFollowing method:

//Keep reading until there are no more FieldRef elements
while (reader.ReadToFollowing("FieldRef"))
{
    //Extract the value of the Name attribute
    string value = reader.GetAttribute("Name");
}

Of course a more flexible and fluent interface is provided by LINQ to XML, perhaps it would be easier to use that if available within the .NET framework you are targeting? The code then becomes:

using System.Xml.Linq;

//Reference to your document
XDocument doc = {document};

/*The collection will contain the attribute values (will only work if the elements
 are descendants and are not direct children of the root element*/
IEnumerable<string> names = doc.Root.Descendants("FieldRef").Select(e => e.Attribute("Name").Value);
Dan Solovay
  • 3,134
  • 3
  • 26
  • 55
James Shuttler
  • 1,344
  • 9
  • 15
  • the problem is, this string is not fixed, some times it will not contains the GroupBy element, some times it will contains OrderBy element. I need to pick the FieldRef and I should know for which root element it belong to. – Waleed Jan 17 '12 at 14:25
  • I noticed that the FieldRef element is not always contained within the same parent node, descendants will account for this and extract it irrespective of the element it is nested within. If you wish to also get the parent element using LINQ to XML, try this: `IEnumerable> pairings = doc.Root.Descendants("FieldRef").Select(e => new KeyValuePair(e.Parent, e.Attribute("Name").Value));` – James Shuttler Jan 17 '12 at 15:52
  • I have a string not a file, how I will define doc varaible? as I see its XDocument type how can I link my string to doc? – Waleed Jan 17 '12 at 16:07
  • @Waleed Sorry I didn't realise that, as long as the string is valid XML (which your posted XML is not, it requires a root node,) then you can use the `XDocument doc = XDocument.Parse({xml});` static method, which is documented on [MSDN](http://msdn.microsoft.com/en-us/library/bb345532.aspx) – James Shuttler Jan 17 '12 at 16:24
  • I am so sorry, but I have an error: 'System.Collections.Generic.IEnumerable' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found (are you missing a using directive or an assembly reference?) Should i define e as XMLElement before? and what value should I give to it? – Waleed Jan 17 '12 at 17:42
  • @Waleed No problem don't be sorry. You need to import the System.Linq namespace, so add this to the top of your code: `using System.Linq;`. That should resolve the issue – James Shuttler Jan 17 '12 at 17:53
  • that is great, I got all information in pairings, but how I pick the specific xelement and store it in string ? I know I should go thorugh loop to get the values, but how? I appreciate your help in the last step here. – Waleed Jan 17 '12 at 18:19
  • What exactly do you mean by 'pick the specific xelement and store it in a string?' The pairings collection within my code above contains a key value pair, with each key holding a reference to the parent XElement and the pair's value is the value of the 'Name' attribute on the FieldRef element. You can use and loop construct you choose, but to extract the value of the Name attribute from each KeyValuePair object, you can do this: `foreach(KeyValuePair pair in pairings){ string nameAttr = pair.Value;}` – James Shuttler Jan 17 '12 at 18:25
  • In my case, when xml tag name includes a ':' - colon, the method goes crazy, throws error 'undeclared prefixes' and closes the app. This is pure madness! Microsoft is doing it wrong! e.g. reader.ReadToFollowing("mnc:MUX") – TomeeNS Jul 11 '17 at 23:01
-1

try this:

    string xml = "<GroupBy Collapse=\"TRUE\" GroupLimit=\"30\"><FieldRef Name=\"Department\" /></GroupBy><OrderBy> <FieldRef Name=\"Width\" /></OrderBy>";
    xml = "<root>" + xml + "</root>";
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xml);
    foreach (XmlNode node in doc.GetElementsByTagName("FieldRef"))
        Console.WriteLine(node.Attributes["Name"].Value);
ojlovecd
  • 4,812
  • 1
  • 20
  • 22
  • the problem is, this string is not fixed, some times it will not contains the GroupBy element, some times it will contains OrderBy element. I need to pick the FieldRef and I should know for which root element it belong to. – Waleed Jan 17 '12 at 14:25