Click here to Skip to main content
15,885,366 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have an xml in which I am trying to grab every child node that start with the name title but only under a parent node named system and has an attribute equal to the value "28". So if the program sees title as a child node under the parent node system but system doesn't have an attribute that equals 28 then it will omit that child node.


public void node()
      {
          XmlTextReader reader = new XmlTextReader(@"C:\pg\ForFun\Node.xml");


          while (reader.Read())
          {

              if (reader.Name == "system")
              {


                  if (!(null == reader.GetAttribute("28")))

                  {
                      XmlReader inner = reader.ReadSubtree();
                      List<string> data = new List<string>();

                      while (inner.Read())
                      {
                          if (reader.Name == "title")
                          {
                              data.Add(reader.ReadString());
                          }
                      }
                      Console.WriteLine(data);
                  }

              }

          }
      }


This is my code when I run the program no error messages shows up however I just get a blank console screen. Appreciate any tips or suggestions

Here is a sample xml

XML
- <infotype infotypevalue="44" id="id4049">
  <infotypename>Removal and Installation</infotypename>
- <servinfo id="GUID-5FCEADFD-AFFA-4E01-B2C5-BA88E8325410">
  <title> Baggae Claims</title>
  <ptxt>GUID-5FCEADFD-AFFA-4E01-B2C5-BA88E8325410.xml</ptxt>
  </servinfo>
  </infotype>
  </component>
  </subsystem>
  </system>
- <system catnbr="28" id="id4051">
  <system-toc groupname="28" />
  <systemname>28 - Value Codes</systemname>
- <component compid="00088" id="id4052">
  <componentname>CLUSTER, Instrument</componentname>
- <infotype infotypevalue="03" id="id4053">
  <infotypename>Tester Class</infotypename>
- <servinfo id="GUID-F3F3BDA2-0DD4-4DD0-9E03-132CC780A889">
  <title>B1000-44-ELECTRONIC CONTROL UNIT - DATA MEMORY FAILURE</title>
  <ptxt>GUID-F3F3BDA2-0DD4-4DD0-9E03-132CC780A889.xml</ptxt>
  </servinfo>
- <servinfo id="GUID-6767D65E-FD48-465C-A304-6F4690C9D174">
  <title>B1000-45-ELECTRONIC CONTROL UNIT - PROGRAM MEMORY FOUND</title>
  <ptxt>GUID-6767D65E-FD48-465C-A304-6F4690C9D174.xml</ptxt>
  </servinfo>


Here is a sample output:
Only nodes under system that has attribute value "28" is selected

CLUSTER, Instrument

B1000-44-ELECTRONIC CONTROL UNIT - DATA MEMORY FAILURE

GUID-F3F3BDA2-0DD4-4DD0-9E03-132CC780A889

B1000-45-ELECTRONIC CONTROL UNIT - PROGRAM MEMORY FOUND

GUID-6767D65E-FD48-465C-A304-6F4690C9D174
Posted
Updated 2-Oct-15 11:37am
v2
Comments
Maciej Los 2-Oct-15 16:01pm    
What's your xml data? What's expected output?
Member 12009796 2-Oct-15 17:38pm    
I have provided sample xml and sample output
Maciej Los 2-Oct-15 18:34pm    
You xml is invalid! Provide complete data!
Member 12009796 2-Oct-15 18:59pm    
It is a very large xmlfile that has unrelated data so that is why I only posted the segment of information that I am actually trying to grab.
Maciej Los 3-Oct-15 17:03pm    
This piece of xml is incomplete (not well-formed). So, i can't provide a solution.

You can't use == to compare strings in C#, because it don't always behave as you expect.
Strictly speaking, if both strings are of type string, == works.
In your program, one part comes from an object and the exact type can be not the same.

http://stackoverflow.com/questions/1659097/why-would-you-use-string-equals-over[^]
http://csharp.net-informations.com/string/csharp-string-compare.htm[^]
http://stackoverflow.com/questions/44288/differences-in-string-compare-methods-in-c-sharp[^]
http://stackoverflow.com/questions/3678792/are-string-equals-and-operator-really-same[^]


Advice: use the debugger to see your code execute step by step, track variables.
The debugger will allow you to see what is doing your code and where/when it don't behave as expected.

PS: Looks like I was a little too fast at answering.
 
Share this answer
 
v4
Comments
Matt T Heffron 2-Oct-15 20:19pm    
This is not true.
Even your second reference says so.
See also: https://msdn.microsoft.com/en-us/library/362314fe(v=vs.120).aspx
Patrice T 2-Oct-15 20:44pm    
Looks like I was a little too quick :)
Is it better now ?
Matt T Heffron 2-Oct-15 20:52pm    
reader.Name property is type string.
And it shouldn't be able to return null, so == should always work in this application.
Patrice T 2-Oct-15 21:04pm    
Ok, and now?
Matt T Heffron 2-Oct-15 21:07pm    
I think the key problem is what I noted in my Solution. The .GetAttribute("28") which won't do what is wanted.
Then the inner.Read() loop is wrong, etc.
Since
C#
reader.GetAttribute("28")
doesn't get the attribute with a value of "28", I'm not surprised you get no output. It gets the attribute with the name of "28", and that wouldn't be a valid attribute name.
So find the correct type of element first.
Then get the attribute by the correct name.
Then check if its value is 28.

The inner.Read() loop should be using inner instead of reader:
C#
while (inner.Read())
{
  if (inner.Name == "title")
  {
    data.Add(inner.ReadString());
  }
}

Finally to write all the strings of a List<string> to the Console, try:
C#
data.ForEach(Console.WriteLine);
 
Share this answer
 
v2
Comments
Member 12009796 3-Oct-15 13:34pm    
Thanks Matt, the problem was the attribute values; once I found the attribute name then saved the value I was able to compile my code with the suggestion to write all the strings.
Matt T Heffron 5-Oct-15 11:44am    
You're welcome.
Please formally "Accept Solution" using the green button above.
Member 12009796 9-Oct-15 8:56am    
Sure no problem...data.Foreach(Console.WriteLine) works successful how can I make the output print to a textfile document the foreach causes problems when I try to use File.WriteAlltext
Matt T Heffron 9-Oct-15 13:21pm    
Just use File.WriteAllLines("path", data);
Member 12009796 9-Oct-15 15:44pm    
Okay perfect and I have one last question. When the program runs it starts reading/grabbing from the data I need but it also keeps reading/grabbing the data to the end rest of the file instead of it staying within the boundaries I want. I tried an else statement but caused a no return output.

XmlTextReader textFile = new XmlTextReader(@"\\Companynet\motordfs\eAcquisition\Chrysler\Service Information\2014\JS - Chrysler 200 & Dodge Avenger\Service_MDS2002si2014JSenUSsvf_Content_AppServer_20140403_1\clocal\www\web-data\service\mds2002\toc\SI2014JSen_US.xml");
string value = null;
string idValue = "";

while (textFile.Read())
{
textFile.MoveToContent();

if (textFile.Name == "system")
{
value = textFile.GetAttribute("catnbr");

if (value == "28")

{
List<string> dtc = new List<string>();

while (textFile.Read())
{
//textFile.MoveToContent();
if(textFile.Name == "componentname")
{
dtc.Add(textFile.ReadString());
}
idValue = textFile.GetAttribute("id");
if (textFile.Name == "servinfo")
{
dtc.Add(idValue);
}
if (textFile.Name == "title")
{
dtc.Add(textFile.ReadString());
}
if (textFile.Name == "ptxt")
{
dtc.Add(textFile.ReadString());
}
}


dtc.ForEach(Console.WriteLine);

}

}

}
I am not sure what I can do in this situation?
Try with Console.WriteLine(data.length + "");

-KR
 
Share this answer
 
Comments
Member 12009796 2-Oct-15 9:04am    
Yeah but since data is declared under a list of string it wouldn't contain a definition for length unfortunately.
Matt T Heffron 2-Oct-15 21:45pm    
How would concatenating the length of the List<string> (should be .Count) with an empty string display the strings in the list?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900