4

I'm using C# to handle an XML file with a repeating structure. The pseudo-document is as follows:

<Root>
    <Element attribute=1> 123 </Element>
    <Element attribute=2> 456 </Element>
    <Element attribute=3> 789 </Element>
</Root>

I'm trying to work with all of this data at once. I figured out (after much experimentation and reading) how to write all of the data within each to (sort of) an array for easy access later. For now, I've just been printing this data to the console for debugging purposes:

XmlNodeList values = xmlDoc.GetElementsByTagName("Element");

for (int i=0; i <= values.Count; i++)
        {   
            Console.WriteLine(values[i].InnerText);
        } 

That part works great. Now, I'm trying to access the attributes of in a similar fashion, and it's just not panning out. After some searching, I came up with

values = xmlDoc.GetElementsByTagName("Element").GetAttribute("attribute");

but that didn't work. How can I add these attributes to a array?

4 Answers 4

1

Firstly, XML is case-sensitive, just as everyone else has stated.

Secondly, You're trying to access a single attribute on an enumeration of elements.

xmlDoc.GetElementsByTagName("Element").GetAttribute("Attribute");

or

Document.ManyElements.SingleAttribute // The cardinality doesn't make sense here.

should be

foreach(var element in Document.ManyElements)
{
    Console.WriteLine(element.SingleAttribute)
}

Thirdly, if you can manage to format your XML properly, I would highly suggest using Linq To XML for this stuff. It's way cleaner to use.

var myXmlText = @"<Root><Element attribute='1'>123</Element></Root>";
var doc = XElement.Parse(myXmlText);

var values = doc.Elements("Element")
                .Attributes("attribute")
                .Select(x => x.Value);

foreach(var value in values)
{
    Console.WriteLine(value);
}
Sign up to request clarification or add additional context in comments.

Comments

1

Attribute names are case-sensitive, just like everything else in XML. So try attribute instead, and see if that works.

2 Comments

Nice remark, but example code (where he tries to extract attributes) doesn't even compile...
Nice catch, but what I posted was pseudo-code. Just a typing error on my part. Will correct in OP.
1

Well, you have to collect all the attribute in a similar fashion of how you print the values:

List<string> attributes = new List<string>();
XmlNodeList elemList = doc.GetElementsByTagName("Element");
for (int i = 0; i < elemList.Count; i++)
{   
     attributes.Add(elemList[i].Attributes["attribute"].Value);
}  

If you use .NET 3.5 or later then you could use Linq to shorten that a bit:

var attributes = doc.GetElementsByTagName("Element").Select(e => e.Attributes["attribute"].Value).ToList();

Comments

1

You can't apply GetAttribute("Attribute") after GetElementsByTagName("Element") because it has XmlNodeList type that doesn't contain GetAttribute method (actually because it represents a list, not element). You have to obtain attributes from each element separately.

Here how you can do it using LINQ (.NET 3.5 and higher):

var list = from XmlNode element in xmlDoc.GetElementsByTagName("Element")
           select element.Attributes["attribute"].Value;

Or using methods:

var list = xmlDoc.GetElementsByTagName("Element")
                 .Cast<XmlNode>()
                 .Select(e => e.Attributes["attribute"].Value);

And output results:

foreach (var attribute in list)
    Console.WriteLine(attribute);

P.S. Your condition i <= values.Count in the loop contains error. Should be i < values.Count. Better use foreach for such purpose.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.