0

I'm struggling with accessing to the data stored in the XML file from C#. I read a lot of posts - the closest one was here - but still can't get it working.

The xml node looks like below:

<Prop Name='StartTime' Type='Number' Flags='0x0'>
<Value>171.8032865</Value>
</Prop>

I need to know what is the value of the property named 'StartTime'

EDIT: The node above is a one of the many in the xml document. And it is nested amongst other nodes. I need to find ALL values of the property with the name 'StartTime'.

I use XAML.

EDIT2: I think it'll better if I display bigger chunk of the xml I have to get the data from. It looks like Kaz's solution is the closest the demanded solution, but it fails if I load whole xml.

XML file:

<Prop Type='TEResult' Flags='0x0'>
<Prop Name='TS' Type='Obj' Flags='0x0'>
    <Prop Name='SequenceCall' Type='Obj' Flags='0x0'>
        <Prop Name='ResultList' Type='Array' LBound='[0]' HBound='[3]' ElementType='Obj' Flags='0x0'>
            <ArrayElementPrototype Type='TEResult' Flags='0x0'>
            </ArrayElementPrototype>
            <Value ID='[0]'>
                <Prop Type='TEResult' Flags='0x0'>
                    <Prop Name='Error' Type='Obj' TypeName='Error' Flags='0x400000'>
                        <Prop Name='Code' Type='Number' Flags='0x400000'>
                            <Value>0</Value>
                        </Prop>
                        <Prop Name='Msg' Type='String' Flags='0x400000'>
                            <Value></Value>
                        </Prop>
                        <Prop Name='Occurred' Type='Boolean' Flags='0x400000'>
                            <Value>False</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Status' Type='String' Flags='0x400000'>
                        <Value>Failed</Value>
                    </Prop>
                    <Prop Name='Numeric' Type='Number' Flags='0x2400'>
                        <Value>0</Value>
                    </Prop>
                    <Prop Name='ReportText' Type='String' Flags='0x400000'>
                        <Value></Value>
                    </Prop>
                    <Prop Name='Common' Type='Obj' TypeName='CommonResults' Flags='0x0'>
                        <Prop Name='IncludeInReport' Type='Boolean' Flags='0x0'>
                            <Value>True</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='TS' Type='Obj' Flags='0x0'>
                        <Prop Name='StartTime' Type='Number' Flags='0x0'>
                            <Value>171.8032865</Value>
                        </Prop>
                        <Prop Name='TotalTime' Type='Number' Flags='0x0'>
                            <Value>0.0005158</Value>
                        </Prop>
                        <Prop Name='Index' Type='Number' Flags='0x0'>
                            <Value>0</Value>
                        </Prop>
                        <Prop Name='StepName' Type='String' Flags='0x0'>
                            <Value>Test 1</Value>
                        </Prop>
                        <Prop Name='StepGroup' Type='String' Flags='0x0'>
                            <Value>Main</Value>
                        </Prop>
                        <Prop Name='StepId' Type='String' Flags='0x0'>
                            <Value>ID#:TbZA+59stkivP1pqe//sUB</Value>
                        </Prop>
                        <Prop Name='Id' Type='Number' Flags='0x0'>
                            <Value>5</Value>
                        </Prop>
                        <Prop Name='StepType' Type='String' Flags='0x0'>
                            <Value>NumericLimitTest</Value>
                        </Prop>
                        <Prop Name='StepCausedSequenceFailure' Type='Boolean' Flags='0x0'>
                            <Value>True</Value>
                        </Prop>
                        <Prop Name='BlockLevel' Type='Number' Flags='0x0'>
                            <Value>0</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Limits' Type='Obj' Flags='0x3000'>
                        <Prop Name='Low' Type='Number' Flags='0x0'>
                            <Value>9</Value>
                        </Prop>
                        <Prop Name='High' Type='Number' Flags='0x0'>
                            <Value>11</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Comp' Type='String' Flags='0x3000'>
                        <Value>GELE</Value>
                    </Prop>
                </Prop>
            </Value>
            <Value ID='[1]'>
                <Prop Type='TEResult' Flags='0x0'>
                    <Prop Name='Error' Type='Obj' TypeName='Error' Flags='0x400000'>
                        <Prop Name='Code' Type='Number' Flags='0x400000'>
                            <Value>0</Value>
                        </Prop>
                        <Prop Name='Msg' Type='String' Flags='0x400000'>
                            <Value></Value>
                        </Prop>
                        <Prop Name='Occurred' Type='Boolean' Flags='0x400000'>
                            <Value>False</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Status' Type='String' Flags='0x400000'>
                        <Value>Failed</Value>
                    </Prop>
                    <Prop Name='Numeric' Type='Number' Flags='0x2400'>
                        <Value>0</Value>
                    </Prop>
                    <Prop Name='ReportText' Type='String' Flags='0x400000'>
                        <Value></Value>
                    </Prop>
                    <Prop Name='Common' Type='Obj' TypeName='CommonResults' Flags='0x0'>
                        <Prop Name='IncludeInReport' Type='Boolean' Flags='0x0'>
                            <Value>True</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='TS' Type='Obj' Flags='0x0'>
                        <Prop Name='StartTime' Type='Number' Flags='0x0'>
                            <Value>171.8135159</Value>
                        </Prop>
                        <Prop Name='TotalTime' Type='Number' Flags='0x0'>
                            <Value>0.0000802</Value>
                        </Prop>
                        <Prop Name='Index' Type='Number' Flags='0x0'>
                            <Value>1</Value>
                        </Prop>
                        <Prop Name='StepName' Type='String' Flags='0x0'>
                            <Value>Test 2</Value>
                        </Prop>
                        <Prop Name='StepGroup' Type='String' Flags='0x0'>
                            <Value>Main</Value>
                        </Prop>
                        <Prop Name='StepId' Type='String' Flags='0x0'>
                            <Value>ID#:7RheSM0MDEGTAnRrrfGNcB</Value>
                        </Prop>
                        <Prop Name='Id' Type='Number' Flags='0x0'>
                            <Value>6</Value>
                        </Prop>
                        <Prop Name='StepType' Type='String' Flags='0x0'>
                            <Value>NumericLimitTest</Value>
                        </Prop>
                        <Prop Name='StepCausedSequenceFailure' Type='Boolean' Flags='0x0'>
                            <Value>False</Value>
                        </Prop>
                        <Prop Name='BlockLevel' Type='Number' Flags='0x0'>
                            <Value>0</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Limits' Type='Obj' Flags='0x3000'>
                        <Prop Name='Low' Type='Number' Flags='0x0'>
                            <Value>9</Value>
                        </Prop>
                        <Prop Name='High' Type='Number' Flags='0x0'>
                            <Value>11</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Comp' Type='String' Flags='0x3000'>
                        <Value>GELE</Value>
                    </Prop>
                </Prop>
            </Value>
            <Value ID='[2]'>
                <Prop Type='TEResult' Flags='0x0'>
                    <Prop Name='Error' Type='Obj' TypeName='Error' Flags='0x400000'>
                        <Prop Name='Code' Type='Number' Flags='0x400000'>
                            <Value>0</Value>
                        </Prop>
                        <Prop Name='Msg' Type='String' Flags='0x400000'>
                            <Value></Value>
                        </Prop>
                        <Prop Name='Occurred' Type='Boolean' Flags='0x400000'>
                            <Value>False</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Status' Type='String' Flags='0x400000'>
                        <Value>Failed</Value>
                    </Prop>
                    <Prop Name='Numeric' Type='Number' Flags='0x2400'>
                        <Value>0</Value>
                    </Prop>
                    <Prop Name='ReportText' Type='String' Flags='0x400000'>
                        <Value></Value>
                    </Prop>
                    <Prop Name='Common' Type='Obj' TypeName='CommonResults' Flags='0x0'>
                        <Prop Name='IncludeInReport' Type='Boolean' Flags='0x0'>
                            <Value>True</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='TS' Type='Obj' Flags='0x0'>
                        <Prop Name='StartTime' Type='Number' Flags='0x0'>
                            <Value>171.8240739</Value>
                        </Prop>
                        <Prop Name='TotalTime' Type='Number' Flags='0x0'>
                            <Value>0.000081</Value>
                        </Prop>
                        <Prop Name='Index' Type='Number' Flags='0x0'>
                            <Value>2</Value>
                        </Prop>
                        <Prop Name='StepName' Type='String' Flags='0x0'>
                            <Value>Test 3</Value>
                        </Prop>
                        <Prop Name='StepGroup' Type='String' Flags='0x0'>
                            <Value>Main</Value>
                        </Prop>
                        <Prop Name='StepId' Type='String' Flags='0x0'>
                            <Value>ID#:pWFWDejvo0GThcOYVssHBA</Value>
                        </Prop>
                        <Prop Name='Id' Type='Number' Flags='0x0'>
                            <Value>7</Value>
                        </Prop>
                        <Prop Name='StepType' Type='String' Flags='0x0'>
                            <Value>NumericLimitTest</Value>
                        </Prop>
                        <Prop Name='StepCausedSequenceFailure' Type='Boolean' Flags='0x0'>
                            <Value>False</Value>
                        </Prop>
                        <Prop Name='BlockLevel' Type='Number' Flags='0x0'>
                            <Value>0</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Limits' Type='Obj' Flags='0x3000'>
                        <Prop Name='Low' Type='Number' Flags='0x0'>
                            <Value>9</Value>
                        </Prop>
                        <Prop Name='High' Type='Number' Flags='0x0'>
                            <Value>11</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Comp' Type='String' Flags='0x3000'>
                        <Value>GELE</Value>
                    </Prop>
                </Prop>
            </Value>
            <Value ID='[3]'>
                <Prop Type='TEResult' Flags='0x0'>
                    <Prop Name='Error' Type='Obj' TypeName='Error' Flags='0x400000'>
                        <Prop Name='Code' Type='Number' Flags='0x400000'>
                            <Value>0</Value>
                        </Prop>
                        <Prop Name='Msg' Type='String' Flags='0x400000'>
                            <Value></Value>
                        </Prop>
                        <Prop Name='Occurred' Type='Boolean' Flags='0x400000'>
                            <Value>False</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Status' Type='String' Flags='0x400000'>
                        <Value>Failed</Value>
                    </Prop>
                    <Prop Name='Numeric' Type='Number' Flags='0x2400'>
                        <Value>0</Value>
                    </Prop>
                    <Prop Name='ReportText' Type='String' Flags='0x400000'>
                        <Value></Value>
                    </Prop>
                    <Prop Name='Common' Type='Obj' TypeName='CommonResults' Flags='0x0'>
                        <Prop Name='IncludeInReport' Type='Boolean' Flags='0x0'>
                            <Value>True</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='TS' Type='Obj' Flags='0x0'>
                        <Prop Name='StartTime' Type='Number' Flags='0x0'>
                            <Value>171.8270851</Value>
                        </Prop>
                        <Prop Name='TotalTime' Type='Number' Flags='0x0'>
                            <Value>0.0001041</Value>
                        </Prop>
                        <Prop Name='Index' Type='Number' Flags='0x0'>
                            <Value>3</Value>
                        </Prop>
                        <Prop Name='StepName' Type='String' Flags='0x0'>
                            <Value>Test 4</Value>
                        </Prop>
                        <Prop Name='StepGroup' Type='String' Flags='0x0'>
                            <Value>Main</Value>
                        </Prop>
                        <Prop Name='StepId' Type='String' Flags='0x0'>
                            <Value>ID#:w+ziJ/u2bkWz+F3kWa4mpC</Value>
                        </Prop>
                        <Prop Name='Id' Type='Number' Flags='0x0'>
                            <Value>8</Value>
                        </Prop>
                        <Prop Name='StepType' Type='String' Flags='0x0'>
                            <Value>NumericLimitTest</Value>
                        </Prop>
                        <Prop Name='StepCausedSequenceFailure' Type='Boolean' Flags='0x0'>
                            <Value>False</Value>
                        </Prop>
                        <Prop Name='BlockLevel' Type='Number' Flags='0x0'>
                            <Value>0</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Limits' Type='Obj' Flags='0x3000'>
                        <Prop Name='Low' Type='Number' Flags='0x0'>
                            <Value>9</Value>
                        </Prop>
                        <Prop Name='High' Type='Number' Flags='0x0'>
                            <Value>11</Value>
                        </Prop>
                    </Prop>
                    <Prop Name='Comp' Type='String' Flags='0x3000'>
                        <Value>GELE</Value>
                    </Prop>
                </Prop>
            </Value>
        </Prop>
        <Prop Name='SequenceFile' Type='String' Flags='0x0'>
            <Value>C:\Users\Public\Documents\National Instruments\TestStand 2010 SP1\Sequence File 16.seq</Value>
        </Prop>
        <Prop Name='Sequence' Type='String' Flags='0x0'>
            <Value>MainSequence</Value>
        </Prop>
        <Prop Name='Status' Type='String' Flags='0x0'>
            <Value>Failed</Value>
        </Prop>
    </Prop>
    <Prop Name='StartTime' Type='Number' Flags='0x0'>
        <Value>171.6948629</Value>
    </Prop>
    <Prop Name='TotalTime' Type='Number' Flags='0x0'>
        <Value>0.1359434</Value>
    </Prop>
    <Prop Name='ModuleTime' Type='Number' Flags='0x0'>
        <Value>0.1357157</Value>
    </Prop>
    <Prop Name='Index' Type='Number' Flags='0x0'>
        <Value>31</Value>
    </Prop>
    <Prop Name='StepName' Type='String' Flags='0x0'>
        <Value>MainSequence Callback</Value>
    </Prop>
    <Prop Name='StepGroup' Type='String' Flags='0x0'>
        <Value>Main</Value>
    </Prop>
    <Prop Name='StepId' Type='String' Flags='0x0'>
        <Value>ID#:xnW0PT0ORE2el7wF7uaxyB</Value>
    </Prop>
    <Prop Name='Id' Type='Number' Flags='0x0'>
        <Value>4</Value>
    </Prop>
    <Prop Name='StepType' Type='String' Flags='0x0'>
        <Value>SequenceCall</Value>
    </Prop>
    <Prop Name='BlockLevel' Type='Number' Flags='0x0'>
        <Value>0</Value>
    </Prop>
    <Prop Name='SequenceFilePostResultListEntry' Type='Obj' Flags='0x0'>
        <Prop Name='ResultList' Type='Array' LBound='[0]' HBound='[]' ElementType='Obj' Flags='0x0'>
            <ArrayElementPrototype Type='TEResult' Flags='0x0'>
            </ArrayElementPrototype>
        </Prop>
        <Prop Name='SequenceFile' Type='String' Flags='0x0'>
            <Value>C:\Program Files\National Instruments\TestStand 2010 SP1\Components\Models\TestStandModels\SequentialModel.seq</Value>
        </Prop>
        <Prop Name='Sequence' Type='String' Flags='0x0'>
            <Value>SequenceFilePostResultListEntry</Value>
        </Prop>
        <Prop Name='Status' Type='String' Flags='0x0'>
            <Value>Passed</Value>
        </Prop>
    </Prop>
</Prop>
Community
  • 1
  • 1
user1146081
  • 195
  • 15
  • The value is 171.8032865 of course! (What have you tried?) – Justin Harvey Nov 10 '14 at 15:37
  • One way would be to look at all elements of root that are named "Prop" and check if they have attributes, maybe an attribute "Name" where the attribute value is "StartTime". Then check, if that element has a child element "Value". And if so, return the value of "Value". There might be Linq to Xml stuff that does that. – Corak Nov 10 '14 at 15:41

6 Answers6

1

You can use XDocument to parse xml,

XDocument doc = XDocument.Load("c:\\somexmlfile.xml");
XElement xProp = doc.Root.Elements().Where(p => p.Attribute("Name").Value == "StartTime").FirstOrDefault();
if (xProp != null)
{
    XElement xValue = xProp.Element("Value");
    if (xValue != null && !string.IsNullOrEmpty(xValue.Value))
    {
       double startTimeValue = double.Parse(xValue.Value);
    }
}
Ryan Mann
  • 5,178
  • 32
  • 42
  • I've problem with build. Error says: Error 1 'System.Xml.Linq.XContainer.Elements()' is a 'method', which is not valid in the given context. I' calling it from within Button_click event in XAML. – user1146081 Nov 10 '14 at 16:37
  • Change Elements to Elements(), my mistake, editing my post now. – Ryan Mann Nov 10 '14 at 17:07
  • I made some more revisions as I forgot to parse the Value element. You can refer to Kaz example below for a nice solution however it could error out if Prop StartTime or it's Child Value element are ever not in the xml response or null values. Which is why I did it the way I did in my answer. At least to the best of my knowledge, linq doesn't auto handle nulls and missing nodes. – Ryan Mann Nov 10 '14 at 17:12
  • Ok, better but still I don't get what I want. I've edited my post pointing that I've a lot of nodes like that to search through so my xml is bigger. The nodes I have to find are nested as well. If I load it and run it I get NullReferenceException: Object reference not set to an instance of an object. – user1146081 Nov 10 '14 at 17:22
1

Your case you can use Below code to get value

string xml = @"<root><Prop Name='StartTime' Type='Number' Flags='0x0'>
<Value>171.8032865</Value>
</Prop></root>";
            var doc = XDocument.Parse(xml);

        foreach (var obj in doc.Descendants("Prop"))
        {
            Console.WriteLine(obj.Element("Value").Value);
        }

Your Xml Is not ideal, Ideally Xml and code should be as below

string xml = @"<root><Prop Name='StartTime' Type='Number' Flags='0x0'>171.8032865</Prop>
                        <Prop Name='StartTime' Type='Number' Flags='0x0'>172.8032865</Prop>
                        </root>";
        var doc = XDocument.Parse(xml);

        foreach (var obj in doc.Descendants("Prop"))
        {
            Console.WriteLine(obj.Value);
        }
Rajnikant
  • 2,176
  • 24
  • 23
1

Just use XmlDocument:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace DemoApp
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(@"
                <Prop Name='StartTime' Type='Number' Flags='0x0'>
                <Value>171.8032865</Value>
                </Prop>");

            XmlElement element = doc.DocumentElement;
            XmlNode valueNode = element.ChildNodes[0];

            double value = double.Parse(valueNode.InnerText);

            Console.ReadLine();
        }
    }
}
BendEg
  • 20,098
  • 17
  • 57
  • 131
1

Ok....after getting the whole xml...

    XDocument xmlDoc = XDocument.Load(@"Your file path");

    var startTimes = xmlDoc.Descendants()
        .Where(x => x.Attributes().Any(att => att.Name == "Name" && att.Value == "StartTime"))
        .Select(x => x.Value).ToList();

This gives me a list containing the values:

  • "171.6948629"
  • "171.8032865"
  • "171.8135159"
  • "171.8240739"
  • "171.8270851"

This feels more like what you're looking for.

Kaz
  • 721
  • 3
  • 15
  • Object reference not set to an instance of an object. Pointing on x => x.Attribute("Name").Value == "StartTime" – user1146081 Nov 10 '14 at 17:39
  • @user1146081 You're right. If "Value" was not present it would error. Updated my solution, should work now. – Kaz Nov 10 '14 at 19:29
  • Again: Object reference not set to an instance of an object. This time pointing on x.Attribute("Name").Value == "StartTime" in if condition. – user1146081 Nov 10 '14 at 20:24
  • Kaz, just edited my initial post. Have a look on my xml. – user1146081 Nov 10 '14 at 20:40
  • OK! Works. Many thanks Kaz for your effort. Do you know where I can learn in more systematic way about accessing xmls from C#? – user1146081 Nov 11 '14 at 09:33
1

You might want to look at the Visual Studio XSD tool. See this Question for more information about how to run it from the command line or by using the Paste Special menu option.

The tool will generate C# classes directly from the XML, which you can then serialize and access programatically.

Edit

Technically, this is not a direct answer (feel free to downvote). However, it does offer an alternative solution that may help solve the bigger problem of reading and writing XML attributes.

Community
  • 1
  • 1
Evil Dog Pie
  • 2,300
  • 2
  • 23
  • 46
0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;


namespace XMLdata
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load("c:\\somexmlfile.xml");
             XmlDocument doc1 = new XmlDocument();
                doc1.LoadXml (doc.ToString());
                XmlElement element = doc1.DocumentElement;
                XmlNode node= element.ChildNodes[0];

            double value = double.Parse(node.InnerText);
        }
    }
}

You can try this