check multiple data with my xml file - c#

i m creating an window application in that i have one label for display the question and one textbox for answering the respective question.then 3 button for check the answer with my xml file and one button for next question and one button for previous question.
this is my xml file
<?xml version="1.0" encoding="utf-8" ?>
<Exam>
<Question number="1" Text="What is IL Code">
<Answer Text="Half compiled, Partially compiled code"> </Answer>
</Question>
<Question number="2" Text="What is JIT">
<Answer Text="IL code to machine language"> </Answer>
</Question>
<Question number="3" Text="What is CLR">
<Answer Text="Heart of the engine , GC , compilation , CAS(Code access security) , CV ( Code verification)"> </Answer>
</Question>
</Exam>
now on button click i want to check the user answer with my xml answer and this part i have done but little problem whenever for the first question that is what is il code for this my code work properly and when the question is changed then my code unable to take the second question every time it take first question and compare with this so how can i achieve this?
below is my snipped code
string[] arrUserAnswer = textBox1.Text.Trim().ToLower().Split(' ');
do
{
XmlReader reader = XmlReader.Create(#"E:\ferozProject\WindowsFormsApplication1\WindowsFormsApplication1\QuestionFile.xml");
reader.Read();
reader.ReadToFollowing("Question");
reader.MoveToContent();
que = reader.GetAttribute("Text");
reader.ReadToFollowing("Answer");
reader.MoveToContent();
string[] arrXMLAnswer = reader.GetAttribute("Text").ToString().Trim().ToLower().Split(' ');
List<string> lststr1 = new List<string>();
if (label2.Text == que)
{
abc = 1;
foreach (string nextStr in arrXMLAnswer)
{
if (Array.IndexOf(arrUserAnswer, nextStr) != -1)
{
lststr1.Add(nextStr);
}
}
if (lststr1.Count > 0)
{
label4.Visible = true;
label4.Text = "Your Answer is " + ((100 * lststr1.Count) / arrXMLAnswer.Length).ToString() + "%" + "Correct";
}
else
{
textBox1.Text = "0 %";
}
}
else
{
reader.ReadToNextSibling("Question");
}
} while (abc <= 0);
abc = 0;
i have also used the second another method for that but in which the code unable to find out my question as because of i have written the question inside the question node, below is my another code.
XmlDocument docQuestionList = new XmlDocument();// Set up the XmlDocument //
docQuestionList.Load(#"E:\ferozProject\WindowsFormsApplication1\WindowsFormsApplication1\QuestionFile.xml"); //Load the data from the file into the XmlDocument //
XmlNodeList QuestionList = docQuestionList.SelectNodes("Exam/Question");
foreach (XmlNode nodexm in QuestionList)
{
string obj = nodexm.SelectNodes("Text").ToString();
if (obj == label2.Text)
{
string[] arrUserAnswer = textBox1.Text.Trim().ToLower().Split(' ');
string[] arrXMLAnswer = nodexm.NextSibling.InnerText.Trim().ToLower().Split(' ');
List<string> lststr1 = new List<string>();
foreach (string nextStr in arrXMLAnswer)
{
if (Array.IndexOf(arrUserAnswer, nextStr) != -1)
{
lststr1.Add(nextStr);
}
}
if (lststr1.Count > 0)
{
label4.Text = "Your Answer is " + ((100 * lststr1.Count) / arrXMLAnswer.Length).ToString() + "%" + "Correct";
}
else
{
textBox1.Text = "0 %";
}
}
}
please help me in any one method

Something like:
//setup the doc
string fn="C:\\bla.xml";
XmlDocument xmlDocument=new XmlDocument();
xmlDocument.Load(fn);
XmlNode root=xmlDocument.DocumentElement;
//get the node
XmlNode answerNode=root.SelectSingleNode("//Question[#number="+num+"]/Answer");
//get the value
string attrName="Text";
XmlAttribute atr=answerNode.Attributes.GetNamedItem(attrName) as XmlAttribute;
if (atr!=null){
string answer=atr.value;
}
will make your life a lot easier. Notice and provide the num variable, and do some null checks.

Related

How to loop XmlTextReader properly (C#)?

Below is a sample of the type of XML file I am trying to handle. If I have only one part along with an accompanying number/character I can process the data extraction without the necessity of the 'if (!reader.EOF)' control structure. However when I try to include this structure so that I can loop back to checking for another part, number, and character group, it deadlocks.
Any advice as to how to do this properly? This was the most efficient idea that popped into my head. I am new to reading data from XMLs.
Sample Xml:
<?xml version="1.0" encoding="UTF-8"?>
<note>
<part>100B</part>
<number>45</number>
<character>a</character>
<part>100C</part>
<number>55</number>
<character>b</character>
</note>
Code:
String part = "part";
String number = "number";
String character = "character";
String appendString = "";
StringBuilder sb = new StringBuilder();
try
{
XmlTextReader reader = new XmlTextReader("myPath");
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // The node is an element.
myLabel:
if (reader.Name == part)
{
part = reader.ReadInnerXml();
}
if (reader.Name == number)
{
number = reader.ReadInnerXml();
number = double.Parse(number).ToString("F2"); //format num
}
if (reader.Name == character)
{
character = reader.ReadInnerXml();
}
//new string
appendString = ("Part: " + part + "\nNumber: " + number +
"\nCharacter: " + character + "\n");
//concatenate
sb.AppendLine(appendString);
if (reader.EOF != true)
{
Debug.Log("!eof");
part = "part";
number = "number";
character = "character";
goto myLabel;
}
//print fully concatenated result
sb.ToString();
//reset string builder
sb.Length = 0;
break;
}
}
}
catch (XmlException e)
{
// Write error.
Debug.Log(e.Message);
}
catch (FileNotFoundException e)
{
// Write error.
Debug.Log(e);
}
catch(ArgumentException e)
{
// Write error.
Debug.Log(e);
}
XmlReader class has many useful methods. Use it.
See this:
var sb = new StringBuilder();
using (var reader = XmlReader.Create("test.xml"))
{
while (reader.ReadToFollowing("part"))
{
var part = reader.ReadElementContentAsString();
sb.Append("Part: ").AppendLine(part);
reader.ReadToFollowing("number");
var number = reader.ReadElementContentAsDouble();
sb.Append("Number: ").Append(number).AppendLine();
reader.ReadToFollowing("character");
var character = reader.ReadElementContentAsString();
sb.Append("Character: ").AppendLine(character);
}
}
Console.WriteLine(sb);
Alexander's answer is fine, I just want to add sample using XDocument, according comments of Jon Skeet:
var sb = new StringBuilder();
var note = XDocument.Load("test.xml").Root.Descendants();
foreach (var el in note)
{
sb.Append(el.Name).Append(": ").AppendLine(el.Value);
}
Console.WriteLine(sb);

Creating a dynamic xml document

Hi you is it possible to create a dynamica xml with xdocument I've been trying but it appears that it returns an exception about having a wrong structure
My code is the following
public string ReadTest(Stream csvFile)
{
XDocument responseXml = new XDocument( new XDeclaration("1.0", "utf-8", "yes"));
try
{
if ( csvFile != null || csvFile.Length!=0)
{
responseXml.Add(new XElement("root"));
//using(CsvFileReader reader=new CsvFileReader(File.OpenRead(#"C:\Users\toshibapc\Documents\Visual Studio 2013\Projects\WCFLecturaCSV\WCFLecturaCSV\App_Data\archivo.csv"))){
using (CsvFileReader reader = new CsvFileReader(csvFile))
{
CsvRow row = new CsvRow();
List<String> headers = new List<string>();
while (reader.ReadRow(row))
{
int cont = 0;
XElement dato = new XElement("AccountInfos", new XElement("Info"));
XElement datos=null;
foreach (String s in row)
{
if(s.Equals("AccountIDToMove", StringComparison.OrdinalIgnoreCase)|| s.Contains("AccountNameToMove") || s.Contains("NewParentAccountID") || s.Contains("NewParentAccountName")){
headers.Add(s);
}
else{
if (s != String.Empty)
{
datos = new XElement(headers[cont], s); //.Append("<" + headers[cont] + ">" + s + "<" + headers[cont] + "/>");
dato.Add(datos);
}
}
cont++;
}
if (headers.Count == 4 && datos != null)
responseXml.Add(dato);
} // fin de while
}
} // Check if no file i sent or not info on file
}
catch (Exception ex) {
//oError = ex.Message;
}
return responseXml.ToString();
}
What i would like to acomplish by using this code is to get an xml like this
<xml version="1.0">
<root>
<AccountInfos>
<Info>
<AccountIDToMove>312456</AccountIDToMove>
<AccountNameToMove>Burger Count</AccountNameToMove>
<NewParentAccountID>453124</NewParentAccountID>
<NewParentAccountName> Testcom sales 1</NewParentAccountName>
</Info>
<Info>
<AccountIDToMove>874145</AccountIDToMove>
<AccountNameToMove>Mac Count</AccountNameToMove>
<NewParentAccountID>984145</NewParentAccountID>
<NewParentAccountName> Testcom sales 1</NewParentAccountName>
</Info>
</AccountInfos>
</root>
For any answer or help thank you so much
You are adding multiple roots to your document. You initially add one here:
responseXml.Add(new XElement("root"));
And later add more root elements in a loop here:
responseXml.Add(dato);
However, each XML document must have exactly one single root element. Thus you probably want to do:
responseXml.Root.Add(dato);

How To Remove Last Node In XML? C#

I am trying to remove the last node from an XML file, but cannot find any good answers for doing this. Here is my code:
XmlReader x = XmlReader.Create(this.PathToSpecialFolder + #"\" + Application.CompanyName + #"\" + Application.ProductName + #"\Recent.xml");
int c = 0;
while (x.Read())
{
if (x.NodeType == XmlNodeType.Element && x.Name == "Path")
{
c++;
if (c <= 10)
{
MenuItem m = new MenuItem() { Header = x.ReadInnerXml() };
m.Click += delegate
{
};
openRecentMenuItem.Items.Add(m);
}
}
}
x.Close();
My XML node structure is as follows...
<RecentFiles>
<File>
<Path>Text Path</Path>
</File>
</RecentFiles>
In my situation, there will be ten nodes maximum, and each time a new one is added, the last must be removed.
You can try this
XmlDocument doc = new XmlDocument();
doc.Load(fileName);
XmlNodeList nodes = doc.SelectNodes("/RecentFiles/File");
nodes[nodes.Count].ParentNode.RemoveChild(nodes[nodes.Count]);
doc.Save(fileName);
It sounds like you want something like:
var doc = XDocument.Load(path);
var lastFile = doc.Descendants("File").LastOrDefault();
if (lastFile != null)
{
lastFile.Remove();
}
// Now save doc or whatever you want to do with it...

Deserialization of XML into Multiple Objects of the Same Type (For Windows 8 App)

So I'm trying to deserialize the following XML Document into multiple objects of my custom type (ItemModel). Since I'm developing for the Windows 8 platform, I've been hitting a lot of blocks due to library incompatibilities. What I'm trying to do is deserialize each ItemModel into an object than add them to a List of some sort. From what I have, the code runs but the list is not populating.
<?xml version="1.0" encoding="utf-8" ?>
<Items>
<ItemModel>
<ID>0</ID>
<Name>Apple</Name>
<Category>Compost</Category>
<ImageWidth>67</ImageWidth>
<ImageHeight>100</ImageHeight>
<Description>An Apple is a compost item that....</Description>
<ImagePath>Graphics\\apple.png</ImagePath>
</ItemModel>
<ItemModel>
<ID>0</ID>
<Name>Water Bottle</Name>
<Category>Mixed Containers</Category>
<ImageWidth>67</ImageWidth>
<ImageHeight>100</ImageHeight>
<Description>A Water bottle is a mixed container item that...</Description>
<ImagePath>Graphics\\Bottle.png</ImagePath>
</ItemModel>
</Items>
Note: I'm also experiencing some trouble using the XmlReader. It's the reader us equal to null even after I use XmlReader.Create().
Thank you.
if you are reading from a .xml file and displaying in Web browser and your code behind is C#, you can do something like this :
protected void Page_Load(object sender, EventArgs e)
{
ReadXmlFile(Server.MapPath("~/XMLFiles/Items.xml"));
}
private void ReadXmlFile(string fileName)
{
string parentElementName = "";
string childElementName = "";
string childElementValue = "";
bool element = false;
lblMsg.Text = "";
XmlTextReader xReader = new XmlTextReader(fileName);
while (xReader.Read())
{
if (xReader.NodeType == XmlNodeType.Element)
{
if (element)
{
parentElementName = parentElementName + childElementName + "<br>";
}
element = true;
childElementName = xReader.Name;
}
else if (xReader.NodeType == XmlNodeType.Text | xReader.NodeType == XmlNodeType.CDATA)
{
element = false;
childElementValue = xReader.Value;
lblMsg.Text = lblMsg.Text + "<b>" + parentElementName + "<br>" + childElementName + "</b><br>" + childElementValue;
parentElementName = "";
childElementName = "";
}
}
xReader.Close();
}
}

how to read attribute data inside node in xml

i m creating an web application in that i m matching the user answer with my xml answer i have done all code and my code work fine then after i have changed my xml format so now i m unable to read the attribute of my xml file node.
and below is my xml file.
<?xml version="1.0" encoding="utf-8" ?>
<Exam>
<Question number="1" Text="What is IL Code">
<Answer Text="Half compiled, Partially compiled code"> </Answer>
</Question>
<Question number="2" Text="What is JIT">
<Answer Text="IL code to machine language"> </Answer>
</Question>
<Question number="3" Text="What is CLR">
<Answer Text="Heart of the engine , GC , compilation , CAS(Code access security) , CV ( Code verification)"> </Answer>
</Question>
</Exam>
and below is my snipped code.
XmlDocument docQuestionList = new XmlDocument();// Set up the XmlDocument //
docQuestionList.Load(#"E:\ferozProject\WindowsFormsApplication1\WindowsFormsApplication1\QuestionFile.xml"); //Load the data from the file into the XmlDocument //
XmlNodeList QuestionList = docQuestionList.SelectNodes("Exam/Question");
foreach (XmlNode nodexm in QuestionList)
{
if (**nodexm.InnerText.Trim()** == label2.Text)
{
string[] arrUserAnswer = textBox1.Text.Trim().ToLower().Split(' ');
string[] arrXMLAnswer = nodexm.NextSibling.InnerText.Trim().ToLower().Split(' ');
List<string> lststr1 = new List<string>();
foreach (string nextStr in arrXMLAnswer)
{
if (Array.IndexOf(arrUserAnswer, nextStr) != -1)
{
lststr1.Add(nextStr);
}
}
if (lststr1.Count > 0)
{
label4.Visible = true;
label4.Text = "Your Answer is "+ ((100 * lststr1.Count) / arrXMLAnswer.Length).ToString() + "%" + "Correct";
}
else
{
label4.Text = "Your Answer is Wrong";
}
}
}
XmlNodeList QuestionList = docQuestionList.SelectNodes("Exam/Question");
the above line you can see that i have read the question node but inside the question node there is attribute like Text in that my question present you can see in my xml file.
if (nodexm.InnerText.Trim() == label2.Text)
in the above line i m matching the screen display question with my xml file question but i can't do that.label2 is used for displaying the question
help me please.
Try this (using System.Linq;
using System.Xml;
using System.Xml.Linq;)
XDocument map = XDocument.Parse("<Exam> " +
"<Question number= \"1\" Text=\"What is IL Code\">" +
" <Answer Text=\"Half compiled, Partially compiled code\"> </Answer>" +
"</Question>" +
"<Question number=\"2\" Text=\"What is JIT\">" +
" <Answer Text=\"IL code to machine language\"> </Answer>" +
"</Question>" +
"<Question number=\"3\" Text=\"What is CLR\">" +
" <Answer Text=\"Heart of the engine , GC , compilation , CAS(Code access security) , CV ( Code verification)\"> </Answer>" +
"</Question>" +
"</Exam>");
var atts = map.Descendants("Question").Attributes().Where(a => a.Name == "Text").ToList();
var QuestionList = map.Descendants("Question").ToList();
foreach (XElement nodexm in QuestionList)
{
if((string)nodexm.Attributes("Text").FirstOrDefault()== label2.Text)
{
string[] arrUserAnswer = textBox1.Text.Trim().ToLower().Split(' ');
string[] arrXMLAnswer = nodexm.Elements("Answer").SelectMany(o => ((string)o.Attribute("Text")).Split(',')).ToArray();
List<string> lststr1 = new List<string>();
foreach (string nextStr in arrXMLAnswer)
{
if (Array.IndexOf(arrUserAnswer, nextStr) != -1)
{
lststr1.Add(nextStr);
}
}
if (lststr1.Count > 0)
{
label4.Visible = true;
label4.Text = "Your Answer is "+ ((100 * lststr1.Count) / arrXMLAnswer.Length).ToString() + "%" + "Correct";
}
else
{
label4.Text = "Your Answer is Wrong";
}
}
}

Categories