2

I'm trying to get information from XML library (file below) using C# in Visual Studio.

<buttons>
<measurement>
    <scan id="0" time="20 53 06">
        <q address="40" state="0"/>
        <q address="41" state="0"/>
        <q address="42" state="1"/>
        <q address="43" state="0"/>
        <q address="44" state="1"/>
        <q address="45" state="1"/>
        <q address="46" state="1"/>
        <q address="47" state="1"/>
    </scan>
</measurement>
<measurement>
    <scan id="1" time="20 53 07">
        <q address="40" state="0"/>
        <q address="41" state="0"/>
        <q address="42" state="0"/>
        <q address="43" state="0"/>
        <q address="44" state="1"/>
        <q address="45" state="0"/>
        <q address="46" state="0"/>
        <q address="47" state="0"/>
    </scan>
</measurement>
<measurement>
    <scan id="2" time="20 53 08">
        <q address="40" state="0"/>
        <q address="41" state="1"/>
        <q address="42" state="0"/>
        <q address="43" state="1"/>
        <q address="44" state="1"/>
        <q address="45" state="0"/>
        <q address="46" state="0"/>
        <q address="47" state="1"/>
    </scan>
</measurement>
<measurement>
    <scan id="3" time="20 53 09">
        <q address="40" state="1"/>
        <q address="41" state="0"/>
        <q address="42" state="0"/>
        <q address="43" state="1"/>
        <q address="44" state="1"/>
        <q address="45" state="0"/>
        <q address="46" state="1"/>
        <q address="47" state="0"/>
    </scan>
</measurement>
<measurement>
    <scan id="4" time="20 53 10">
        <q address="40" state="0"/>
        <q address="41" state="0"/>
        <q address="42" state="1"/>
        <q address="43" state="1"/>
        <q address="44" state="1"/>
        <q address="45" state="1"/>
        <q address="46" state="0"/>
        <q address="47" state="0"/>
    </scan>
</measurement>
<measurement>
    <scan id="5" time="20 53 11">
        <q address="40" state="1"/>
        <q address="41" state="1"/>
        <q address="42" state="1"/>
        <q address="43" state="0"/>
        <q address="44" state="0"/>
        <q address="45" state="0"/>
        <q address="46" state="1"/>
        <q address="47" state="0"/>
    </scan>
</measurement>
<measurement>
    <scan id="6" time="20 53 12">
        <q address="40" state="0"/>
        <q address="41" state="1"/>
        <q address="42" state="1"/>
        <q address="43" state="0"/>
        <q address="44" state="0"/>
        <q address="45" state="1"/>
        <q address="46" state="1"/>
        <q address="47" state="1"/>
    </scan>
</measurement>
<measurement>
    <scan id="7" time="20 53 13">
        <q address="40" state="1"/>
        <q address="41" state="1"/>
        <q address="42" state="1"/>
        <q address="43" state="1"/>
        <q address="44" state="1"/>
        <q address="45" state="0"/>
        <q address="46" state="1"/>
        <q address="47" state="1"/>
    </scan>
</measurement>

it is my first attempt to do and read xml files.

Hre is what i want to do:
I want to inpud ID and program schould return all q states in array.

Here is what I tried:

using System.Xml;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("Path to my xml");
XmlNodeList titleNodes = xmlDoc.SelectNodes("//buttons/measurment/scan/q");
foreach(XmlNode titleNode in titleNodes)
    Console.WriteLine(titleNode.Attribute["address"]);
Console.ReadKey();

I know that this code will only display some q atributes in console. I never went furder because it is not working (nothing appears in console window) . And i dont know why. I just don understand this XmlRead, XmlDeocument. I was learnig form here: Tutorial. I was folowing every stem and examlpes. Only XmlRead giave something to me. Bu it reads just everything, not specific regions.

Can you show me some examples or solutions?

5
  • 1
    I'm not looking into this too much, but your SelectNodes has the wrong casing - Try changing the upper case "Q" - "//buttons/measurment/scan/q" Commented Aug 23, 2016 at 12:50
  • you input the scan id, and get all the q states? is that what you're asking Commented Aug 23, 2016 at 12:54
  • My mistake during prescribing Commented Aug 23, 2016 at 12:55
  • All q states from specific scan area. For examle tag scan has atribute id="0" and i wan all q states from this tag area. Commented Aug 23, 2016 at 12:56
  • What you want to do is something like this: SelectNodes("//scan[contains(id,""'YOURSELECTEDID'"")]") Commented Aug 23, 2016 at 12:58

3 Answers 3

3

Consider using XDocument, which allows you to use LINQ, making your xml life easier:

string myId = "2";

var doc = XDocument.Parse(xmlString); //or XDocument.Load(filePath)

//find the correct 'scan' node based on your id
var scan = doc.Descendants("scan")
              .FirstOrDefault(s => s.Attribute("id").Value == myId);

//grab all q's and get their 'state' for that 'scan' node
var states = scan?.Descendants("q")
                  .Select(q => q.Attribute("state").Value);

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

6 Comments

If the scan is null (when the id is not found), you'll get a NullReferenceException in the foreach... so ?. only puts it off to the next instruction
I'd suggest a var states = scan?.Descendants("q").Select(q => q.Attribute("state").Value) ?? Enumerable.Empty <string>(); :-) but of course there are thousand ways...
This solution looks good, but VisualStudio don't recodnise XDocument. And yes I added System.Linq library.
@MrJW the namespace for XDocument is System.Xml.Linq and minimum .Net Framework is 3.5 (Visual Studio 2008)
I typed file path, for example "XDocument.Parse(/data/test.xml)" file test.xml containt data described in my main post. I also added library System.Xml.Linq but when I run application, excepion unhandle apperars: "An unhandled exception of type 'System.Xml.XmlException' occurred in System.Xml.dll Additional information: Data at the root level is invalid. Line 1, position 1. "
|
1

Assuming the xml is well formed and the root node is corectly closed, you have a typo in the string measurement and this is correctly selecting all the q tags

XmlNodeList titleNodes = xmlDoc.SelectNodes("//buttons/measurement/scan/q");

If you want only the ones under one id

XmlNodeList titleNodes = xmlDoc.SelectNodes("//buttons/measurement/scan[@id=2]/q") ;

If there is no such id, you'll get an empty collection but not an exception error: so that case is managed.

Finally, don't forget the Value field

Console.WriteLine(titleNode.Attributes["address"].Value);

2 Comments

Your solution looks the best, but (i don't know why) Attributes are not recognised. I just get red line under this word. And sorry for typos. I'm not a native english speaker,I translated my code so it is more redable here.
After some tweaking everything works( my part of the code, your is perfect :) ). Thanks, you helped me alot :)
0
XmlNodeList titleNodes = xmlDoc.SelectNodes("//measurement/scan/q");

Then you will get 64 items back.

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.