In .xml parsing how to skip subnodes and move to next node usingXmlTextReader

R

raghudr

Hi all,

I am parsing a .xml file.My main intention is to retrieve the name
value of node "Signal":- "Name Value" which is

"rag".

i want to store only the <signal> "name value" that is only
"rag" ,"rock","yahoo"to my list.
I do not want to add any <subsignals> "name value" to the list.i want
to skip it.

For that i wrote code like this


XmlTextReader reader = new XmlTextReader(signalfilename);
while (reader.Read())
{


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

//save the name value to list
}
else if (reader.Name == "SubSignals")
{
Problem:- Which is the API i have to use to skip all the
subnodes of the <subsignals> and go to the
next <signal>

}


}

Fot that i wrote code like this:

<Signal>
<Name Value="rag" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<SubSignals>
<Signal BitIndex="0">
<Name Value="jack" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
<Signal BitIndex="1">
<Name Value="jae" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
<Signal BitIndex="2">
<Name Value="chuck" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
</SubSignals>
</Signal>
<Signal>
<Name Value="rock" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<Signal>
<Signal>
<Name Value="yahoo" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<Signal>



can anyone tell me what changes i need to do to my above code.

thanks in advance,
RAGHU
 
M

Morten Wennevik [C# MVP]

Hi all,

I am parsing a .xml file.My main intention is to retrieve the name
value of node "Signal":- "Name Value" which is

"rag".

i want to store only the <signal> "name value" that is only
"rag" ,"rock","yahoo"to my list.
I do not want to add any <subsignals> "name value" to the list.i want
to skip it.

For that i wrote code like this


XmlTextReader reader = new XmlTextReader(signalfilename);
while (reader.Read())
{


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

//save the name value to list
}
else if (reader.Name == "SubSignals")
{
Problem:- Which is the API i have to use to skip all the
subnodes of the <subsignals> and go to the
next <signal>

}


}

Fot that i wrote code like this:

<Signal>
<Name Value="rag" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<SubSignals>
<Signal BitIndex="0">
<Name Value="jack" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
<Signal BitIndex="1">
<Name Value="jae" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
<Signal BitIndex="2">
<Name Value="chuck" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
</SubSignals>
</Signal>
<Signal>
<Name Value="rock" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<Signal>
<Signal>
<Name Value="yahoo" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<Signal>



can anyone tell me what changes i need to do to my above code.

thanks in advance,
RAGHU

Hi,

Assuming you have a properly formed xml you can easily extract just those
nodes using an XPath expression.


XmlDocument doc = new XmlDocument();
doc.Load(@"C:\signals.xml");

XmlNodeList nodes = doc.SelectNodes(@"*/Signal/Name");

StringBuilder sb = new StringBuilder();
foreach (XmlNode node in nodes)
sb.AppendLine(node.Attributes["Value"].Value);
 
M

Martin Honnen

I am parsing a .xml file.My main intention is to retrieve the name
value of node "Signal":- "Name Value" which is

"rag".

i want to store only the <signal> "name value" that is only
"rag" ,"rock","yahoo"to my list.

Fot that i wrote code like this:

<Signal>
<Name Value="rag" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<SubSignals>
<Signal BitIndex="0">
<Name Value="jack" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
<Signal BitIndex="1">
<Name Value="jae" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
<Signal BitIndex="2">
<Name Value="chuck" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
</SubSignals>
</Signal>

This is not a well-formed XML document as the Signal elements need a
commen root element and as
<Signal>
<Name Value="rock" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<Signal>

this needs to be said:
<Signal>
<Name Value="yahoo" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<Signal>

this too.

So assuming your XML looks like this

<root>
<Signal>
<Name Value="rag" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
<SubSignals>
<Signal BitIndex="0">
<Name Value="jack" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
<Signal BitIndex="1">
<Name Value="jae" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
<Signal BitIndex="2">
<Name Value="chuck" />
<Reference Value="" />
<Description Value="AIR_PRG" />
<Min Value="11" />
<Max Value="13" />
<Unit Value="ACTIVE" />
<DataType Value="VT" />
</Signal>
</SubSignals>
</Signal>
<Signal>
<Name Value="rock" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
</Signal>
<Signal>
<Name Value="yahoo" />
<Real Value="21@ADVANT" />
<Description Value="Best" />
<Min Value="0" />
<Max Value="40" />
<Unit Value="barh" />
<Item Value="XQ60" />
<MillisCylce Value="20" />
<Resolution Value="1" />
<DataType Value="VT" />
</Signal>
</root>


then you can use the following code:

List<string> values = new List<string>();

XmlReaderSettings rs = new XmlReaderSettings();
rs.IgnoreWhitespace = true;

using (XmlReader rd = XmlReader.Create(@"file.xml", rs))
{
while (rd.Read())
{
if (rd.Depth == 1 && rd.IsStartElement() && rd.Name
== "Signal")
{
rd.ReadToDescendant("Name");
values.Add(rd.GetAttribute("Value"));
}
}
}

foreach (string value in values)
{
Console.WriteLine(value);
}
 
R

raghudr

This is not a well-formed XML document as the Signal elements need a
commen root element and as




this too.

So assuming your XML looks like this

<root>
   <Signal>
     <Name Value="rag" />
     <Real Value="21@ADVANT" />
     <Description Value="Best" />
     <Min Value="0" />
     <Max Value="40" />
     <Unit Value="barh" />
     <Item Value="XQ60" />
     <MillisCylce Value="20" />
     <Resolution Value="1" />
     <DataType Value="VT" />
     <SubSignals>
       <Signal BitIndex="0">
         <Name Value="jack" />
         <Reference Value="" />
         <Description Value="AIR_PRG" />
         <Min Value="11" />
         <Max Value="13" />
         <Unit Value="ACTIVE" />
         <DataType Value="VT" />
       </Signal>
       <Signal BitIndex="1">
         <Name Value="jae" />
         <Reference Value="" />
         <Description Value="AIR_PRG" />
         <Min Value="11" />
         <Max Value="13" />
         <Unit Value="ACTIVE" />
         <DataType Value="VT" />
       </Signal>
       <Signal BitIndex="2">
         <Name Value="chuck" />
         <Reference Value="" />
         <Description Value="AIR_PRG" />
         <Min Value="11" />
         <Max Value="13" />
         <Unit Value="ACTIVE" />
         <DataType Value="VT" />
       </Signal>
     </SubSignals>
   </Signal>
   <Signal>
     <Name Value="rock" />
     <Real Value="21@ADVANT" />
     <Description Value="Best" />
     <Min Value="0" />
     <Max Value="40" />
     <Unit Value="barh" />
     <Item Value="XQ60" />
     <MillisCylce Value="20" />
     <Resolution Value="1" />
     <DataType Value="VT" />
   </Signal>
   <Signal>
         <Name Value="yahoo" />
         <Real Value="21@ADVANT" />
         <Description Value="Best" />
         <Min Value="0" />
         <Max Value="40" />
         <Unit Value="barh" />
         <Item Value="XQ60" />
         <MillisCylce Value="20" />
         <Resolution Value="1" />
         <DataType Value="VT" />
   </Signal>
</root>

then you can use the following code:

             List<string> values = new List<string>();

             XmlReaderSettings rs = new XmlReaderSettings();
             rs.IgnoreWhitespace = true;

             using (XmlReader rd = XmlReader.Create(@"file.xml", rs))
             {
                 while (rd.Read())
                 {
                     if (rd.Depth == 1 && rd.IsStartElement() && rd.Name
== "Signal")
                     {
                         rd.ReadToDescendant("Name");
                         values.Add(rd.GetAttribute("Value"));
                     }
                 }
             }

             foreach (string value in values)
             {
                 Console.WriteLine(value);
             }

--

        Martin Honnen --- MVP XML
       http://JavaScript.FAQTs.com/- Hide quoted text -

- Show quoted text -

Three cheers to Morten and Martin!!

But one more thing i want to do!!

I had to remove the rd.depth coz it is a big .xml files in some MB's

while (rd.Read())
{

if (rd.IsStartElement()&& rd.Name == "Signal")
{
rd.ReadToDescendant("Name");
values.Add(rd.GetAttribute("Value"));

problem:- //after retrieving the the "Name value"
instead of rd.read() parsing all the other elements like
from "real value" ,,,,,,,-
............."Datatype".can't we just move th rd.read() to the next
<signal> node
i feel it may take up some time to read each
element by element.The code would be more optimized if
we can jump to the other<signal> node after
storing the "name value" of the <signal>.

requesting to reply on this

}
else if (rd.Name == "SubSignals")
{
rd.Skip();
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top