XML to local database in windows phone 7 - c#

This function (look CODE) occur when xml file is downloaded from my server.. Now I want to load it in my local database...
XML
<?xml version="1.0" encoding="utf-8" ?>
<Questions>
<idQuestion>1</idQuestion>
<Question>Question 1</Question>
<CorrectAns>Ans1</CorrectAns>
<WrongAns1>Ans2</WrongAns1>
<WrongAns2>Ans3</WrongAns2>
<WrongAns3>Ans4</WrongAns3>
<Category>CategoryName</Category>
</Questions>
<Questions>
<idQuestion>2</idQuestion>
<Question>Question 2</Question>
<CorrectAns>Ans1</CorrectAns>
<WrongAns1>Ans2</WrongAns1>
<WrongAns2>Ans3</WrongAns2>
<WrongAns3>Ans4</WrongAns3>
<Category>CategoryName</Category>
</Questions>
etc...
CODE:
void downloader_Completed(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
return;
XElement quest = XElement.Parse(e.Result);
using (QuestionContext context = new QuestionContext(ConnectionString))
{
for (int i = 0; i < quest.Length; i++)
{
Question q = new Question();
q.idQuestion = ;
q.Question = ;
q.CorrectAns = ;
q.WrongAns1 = ;
q.WrongAns2 = ;
q.WrongAns3 = ;
context.QuestionsDB.InsertOnSubmit(q);
context.SubmitChanges();
}
}
}
I have 2 questions:
1)How to read the xml content and write them in:
q.idQuestion = ;
q.Question = ;
q.CorrectAns = ;
q.WrongAns1 = ;
q.WrongAns2 = ;
q.WrongAns3 = ;
2)for (int i = 0; i < quest.Length; i++) Herequest.Length give error (I know why)... How to make custom function to get the length? I need it to count <Questions> tags

Your xaml is not in valid format, because it has multiple root elements (Questions).
Assuming if it is in the correct format like this (I have modifiec)
string xmlData = #"<?xml version=""1.0"" encoding=""utf-8"" ?>
<Questions>
<Question>
<idQuestion>1</idQuestion>
<QuestionName>Question 1</QuestionName>
<CorrectAns>Ans1</CorrectAns>
<WrongAns1>Ans2</WrongAns1>
<WrongAns2>Ans3</WrongAns2>
<WrongAns3>Ans4</WrongAns3>
<Category>CategoryName</Category>
</Question>
<Question>
<idQuestion>2</idQuestion>
<QuestionName>Question 2</QuestionName>
<CorrectAns>Ans1</CorrectAns>
<WrongAns1>Ans2</WrongAns1>
<WrongAns2>Ans3</WrongAns2>
<WrongAns3>Ans4</WrongAns3>
<Category>CategoryName</Category>
</Question>
</Questions>";
You can have any number of tags as above
Now, you can convert this data into classes as shown below
XElement quest = XElement.Parse(xmlData);
var questionsData = from qn in quest.Descendants("Question")
select new Question
{
idQuestion = int.Parse(qn.Element("idQuestion").Value),
QuestionName = qn.Element("QuestionName").Value,
CorrectAns = qn.Element("CorrectAns").Value,
WrongAns1 = qn.Element("WrongAns1").Value,
WrongAns2 = qn.Element("WrongAns2").Value,
WrongAns3 = qn.Element("WrongAns3").Value
};
var Questions = questionsData.ToList();
var noofquestions = Questions.Count;
//If you want any question with specific id, say '2'
int idQuestion = 2;
var question = Questions.Where(item => item.idQuestion == idQuestion).First();
Here my Question class is like this
class Question
{
public int idQuestion ;
public string QuestionName ;
public string CorrectAns ;
public string WrongAns1 ;
public string WrongAns2 ;
public string WrongAns3 ;
}
Now apply the above process to your data, in whatever way applies

Related

XML traversal by path in c#

I have an XML like this I want to get Return/ReturnHeader not EliminationsConsolidatedReturn/ReturnHeader. I want to traverse the XML by a path like Return/ReturnHeader. I got this function in c#. The issue is when I set the path Return/ReturnHeader is also getting the ReturnHeader of all inside EliminationsConsolidatedReturn,ParentReturn and SubsidiaryReturn. Please help me fix this.
c#
private List<XElement> GetNode(XNamespace nameSpace, string path)
{
var names = path.Split("\\".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var element = new List<XElement>() { XDocument.Descendants(NameSpace + names[0]).FirstOrDefault() };
for (int i = 1; i < names.Length; i++)
{
var name = names[i];
element = element.Descendants(XName.Get(name, nameSpace.ToString())).ToList();
}
return element;
}
XML
<?xml version="1.0" encoding="utf-8"?>
<Return returnVersion="2014v4.0" xmlns="http://www.irs.gov/efile" xmlns:efile="http://www.irs.gov/efile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ReturnHeader binaryAttachmentCnt="45" subsidiaryReturnCount="18">
</ReturnHeader>
<EliminationsConsolidatedReturn>
<ReturnHeader>
</ReturnHeader>
</EliminationsConsolidatedReturn>
<ParentReturn>
<ReturnHeader>
</ReturnHeader>
</ParentReturn>
<SubsidiaryReturn>
<ReturnHeader>
</ReturnHeader>
</SubsidiaryReturn>
</Return>
private List<XElement> GetNode(XNamespace nameSpace, string path)
{
var names = path.Split("\\".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var element = new List<XElement>() { XDocument.Descendants(NameSpace + names[0]).FirstOrDefault() };
for (int i = 1; i < names.Length; i++)
{
var name = names[i];
element = element.Elements().Where(q => q.Name.LocalName == name).ToList();
}
return element;
}

C# XDocument right way to escape symbols

Hello I'm struggling with escaping in xml, problem is my output is escaped 2 times and I dont understand why its happening.
Code below:
private static string FixSingleEncoding(string data)
{
//data?.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace(""", """).Replace("'", "&apos;");
return System.Net.WebUtility.HtmlEncode(data); //SecurityElement.Escape(data);//
}
private static XDocument FixEncoding(XDocument instance)
{
XNamespace naming = instance.Root.Name.Namespace;
var result = instance.Descendants(naming + "dataset").ToList();
var count = result.Count;
for (int i = 0; i < count; i++)
{
result[i].Value = FixSingleEncoding(result[i].Value);
}
return instance;
}
public static bool CreateNewDataset(string path, string data)
{
Debug.WriteLine("CALL");
XDocument xdoc = XDocument.Load(Path.Combine(MasterLocation, path));
xdoc = FixEncoding(xdoc);
XNamespace df = xdoc.Root.Name.Namespace;
XElement root = new XElement(df+"changeSet");
root.Add(new XAttribute("id", "My Name"));
root.Add(new XAttribute("author", "Test"));
string final = data;
XElement innerelement = new XElement(df + "data", final);
innerelement.Add(new XAttribute("endDelimiter", "GO"));
root.Add(innerelement);
xdoc.Root.Add(root);
xdoc.Save(Path.Combine(MasterLocation, path));
return true;
}
Problem is when I first time load xml file and use method CreateNewDataset it retrieves all data from xml file and unescape old data, so I put FixEncoding method, but then another problem showed up, now it escapes two times, how do I know that exactly two times, well using VS Code and converting XML Entity to string, it needs to converted 2 times to readable string, CreateNewDataset method is called only once, but data escaped two times, what do I miss here?
entered data
IF EXISTS ( SELECT *
FROM sysobjects
WHERE id = object_id(N'[dbo].[table1]')
and OBJECTPROPERTY(id, N'IsProcedure') = 0)
orginal code before CreateNewDataset:
<changeSet id="Test" author="My Name">
<data endDelimiter="GO">
IF EXISTS ( SELECT *
FROM sysobjects
WHERE id = object_id(N&apos;[dbo].[table1]&apos;)
and OBJECTPROPERTY(id, N&apos;IsProcedure&apos;) = 0)
</data>
</changeSet>
AFTER createnewdataset(without FixEncoding)
<changeSet id="Test" author="My Name">
<data endDelimiter="GO">
IF EXISTS ( SELECT *
FROM sysobjects
WHERE id = object_id(N'[dbo].[table1]')
and OBJECTPROPERTY(id, N'IsProcedure') = 0)
</data>
</changeSet>

Convert a XML to CSV using C#

How to convert a XML file to a CSV file in C#, showing only these Tags: <original-impot-no>, <price>, <Small-price>, <Big-price>?
sample XML code: it represents one line among several lines, and every line may contains several <product-lineitem>Tags
<?xml version="1.0" encoding="UTF-8"?>
<impots xmlns="http://www.google.com/xml/impot//20016-02-31">
<impot impot-no="W0110891258">
<impot-date>2017-12-10T22:33:35.000Z</impot-date>
<prop-by>Yallo</prop-by>
<original-impot-no>891258</original-impot-no>
<currency>EUR</currency>
<server-locale>Esp</server-locale>
<lax>gross</lax>
<current-impot-no>123358</current-impot-no>
<product-lineitems>
<product-lineitem>
<price>450</price>
<red>6.50</red>
<Small-price>39</Small-price>
<Big-price>3229</Big-price>
<lineitem-text>Grand create</lineitem-text>
<basis>234.00</basis>
</product-lineitem>
</product-lineitems>
<product-lineitem>
<price>432</price>
<red>12</red>
<Small-price>44</Small-price>
<Big-price>34</Big-price>
<lineitem-text>Small create</lineitem-text>
<basis>44.00</basis>
</product-lineitem>
</product-lineitems>
</impot>
</impots>
I should get someting like this in y CSV file:
891258;450;39;229
891258;432;44;34
the C# code:
the problem that Im facing with this code is that I can not retrieve the descandent of the TAG <impot>
XmlTextReader xtr = new XmlTextReader(#"C:\Temp_Convert\Impot.xml");
StringBuilder dataToBeWritten = new StringBuilder();
while (xtr.Read())
{
if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "original-impot-no")
{
string s1 = xtr.ReadElementString();
dataToBeWritten.Append(s1);
dataToBeWritten.Append(";");
}
else if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "price")
{
string s2 = xtr.ReadElementString();
dataToBeWritten.Append(s2);
dataToBeWritten.Append(";");
}
else if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "Small-price")
{
string s2 = xtr.ReadElementString();
dataToBeWritten.Append(s2);
dataToBeWritten.Append(";");
dataToBeWritten.Append(0);
dataToBeWritten.Append(Environment.NewLine);
}
else if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "Big-price")
{
string s2 = xtr.ReadElementString();
dataToBeWritten.Append(s2);
dataToBeWritten.Append(";");
dataToBeWritten.Append(0);
dataToBeWritten.Append(Environment.NewLine);
}
}
File.WriteAllText(#"C:\Temp_Convert\Impot.csv", dataToBeWritten.ToString());
}
Can somebody please propose a solution, thank you so much in advance.
You have an invalid XML. I guess here is the correct format.
<?xml version="1.0" encoding="UTF-8"?>
<impots xmlns="http://www.google.com/xml/impot//20016-02-31">
<impot impot-no="W0110891258">
<impot-date>2017-12-10T22:33:35.000Z</impot-date>
<prop-by>Yallo</prop-by>
<original-impot-no>891258</original-impot-no>
<currency>EUR</currency>
<server-locale>Esp</server-locale>
<lax>gross</lax>
<current-impot-no>123358</current-impot-no>
<product-lineitems>
<product-lineitem>
<price>450</price>
<red>6.50</red>
<Small-price>39.00</Small-price>
<Big-price>3229.00</Big-price>
<lineitem-text>Grand create</lineitem-text>
<basis>234.00</basis>
</product-lineitem>
</product-lineitems>
<product-lineitems>
<product-lineitem>
<price>432</price>
<red>12</red>
<Small-price>44.00</Small-price>
<Big-price>34.00</Big-price>
<lineitem-text>Small create</lineitem-text>
<basis>44.00</basis>
</product-lineitem>
</product-lineitems>
</impot>
</impots>
You couldn't retrieve the descendant because you are not including the namespace http://www.google.com/xml/impot//20016-02-31.
Here is how the code should be.
XNamespace ns = "http://www.google.com/xml/impot//20016-02-31";
var results = xDocument.Descendants(ns + "impot");
Then, you need to modify your query to retrieve elements that you need.
Here is the sample. I assume that product-lineitems only has one child product-lineitem.
var results = xDocument.Descendants(ns + "impot").Select(x => new {
ImpotNo = x.Attribute("impot-no")?.Value,
ProductLineItems = x.Descendants(ns + "product-lineitems").Select(y => new
{
Item = y.Descendants(ns + "product-lineitem").Select(z => new
{
Price = z.Element(ns + "price")?.Value,
SmallPrice = z.Element(ns + "Small-price")?.Value,
BigPrice = z.Element(ns + "Big-price")?.Value,
}).FirstOrDefault()
})
});
foreach (var result in results)
{
foreach (var productLine in result.ProductLineItems)
{
dataToBeWritten.Append(result.ImpotNo);
dataToBeWritten.Append(";");
dataToBeWritten.Append(productLine.Item.Price);
dataToBeWritten.Append(";");
dataToBeWritten.Append(productLine.Item.SmallPrice);
dataToBeWritten.Append(";");
dataToBeWritten.Append(productLine.Item.BigPrice);
dataToBeWritten.Append(";");
dataToBeWritten.Append(0);
dataToBeWritten.Append(Environment.NewLine);
}
}
Well, first I tried to reformat your XML to be a bit more readable but the tag structure still seems wrong...
<impots
xmlns="http://www.google.com/xml/impot//20016-02-31">
<impot impot-no="W0110891258">
<impot-date>2017-12-10T22:33:35.000Z</impot-date>
<prop-by>Yallo</prop-by>
<original-impot-no>891258</original-impot-no>
<currency>EUR</currency>
<server-locale>Esp</server-locale>
<lax>gross</lax>
<current-impot-no>123358</current-impot-no>
<product-lineitems>
<product-lineitem>
<price>450</price>
<red>6.50</red>
<Small-price>39.00</Small-price>
<Big-price>3229.00</Big-price>
<lineitem-text>Grand create</lineitem-text>
<basis>234.00</basis>
-
</product-lineitems>
-
</product-lineitem>
<product-lineitems>
<product-lineitem>
<price>432</price>
<red>12</red>
<Small-price>44.00</Small-price>
<Big-price>34.00</Big-price>
<lineitem-text>Small create</lineitem-text>
<basis>44.00</basis>
</product-lineitems>
</product-lineitem>
Nonetheless, I'm guessing this line is incorrect since "impot-no" is an attribute...
impot-no = (string)x.Element("impot impot-no")
Perhaps you meant that line to be...
impot-no = (string)x.Attribute("impot-no").Value
Going by memory -- hopefully that is the correct way to retrieve an attribute.
Review the following code. Note the use of SelectMany to get the impot items to construct the desired object models.
XNamespace ns = "http://www.google.com/xml/impot//20016-02-31";
var results = xDocument.Descendants(ns + "impot")
.SelectMany(impot => impot.Descendants(impot.Name.Namespace + "product-lineitem")
.Select(item => new {
ImpotNo = (string)impot.Element(impot.Name.Namespace + "original-impot-no"),
Price = (string)item.Element(item.Name.Namespace + "price"),
SmallPrice = (string)item.Element(item.Name.Namespace + "Small-price"),
BigPrice = (string)item.Element(item.Name.Namespace + "Big-price"),
})
).ToList();
for (int i = 0; i < results.Count; i++) {
dataToBeWritten.Append(results[i].ImpotNo);
dataToBeWritten.Append(";");
dataToBeWritten.Append(results[i].Price);
dataToBeWritten.Append(";");
dataToBeWritten.Append(results[i].SmallPrice);
dataToBeWritten.Append(";");
dataToBeWritten.Append(results[i].BigPrice);
dataToBeWritten.Append(";");
dataToBeWritten.Append(0);
dataToBeWritten.Append(Environment.NewLine);
}
Also note the syntax used for the properties.

C#: How to make a list from few string variables and put this to SOAP string

I have a problem with making a list from few variables.
i.e.:
var pos = "1; 2; 3"
var des = "aaa; bbb; ccc"
var pcs = "1.000; 44.000; 65.000"
I need to put this to something like list where I can use this data in soap string block.
data from these variables are an invoice lines like:
pos; des; pcs
1; aaa; 1.000
2; bbb; 44.000
3; ccc; 65.000
And finally I have to put this lines to blocks in SOAP message like this (one line is one RECEIVE_EINVOICE_LINE block which must be replicated with amount of lines):
<urn:LINES>
<urn:RECEIVE_EINVOICE_LINE>
<!--Optional:-->
<urn:C00></urn:C00> <!-- pos-->
<!--Optional:-->
<urn:C14></urn:C14> <!-- des-->
<!--Optional:-->
<urn:D00></urn:D00> <!-- pcs-->
</urn:RECEIVE_EINVOICE_LINE>
<urn:RECEIVE_EINVOICE_LINE>
<!--Optional:-->
<urn:C00></urn:C00> <!-- pos-->
<!--Optional:-->
<urn:C14></urn:C14> <!-- des-->
<!--Optional:-->
<urn:D00></urn:D00> <!-- pcs-->
</urn:RECEIVE_EINVOICE_LINE>
</urn:LINES>
I'm really noob but I need to do this.
I have an idea to put this lines into lists but I don't know how to separate data from this variables and then merge this and put data into this soap message.
I tried to split this properly but I stucked with something like this:
class Program
{
public void Pozycja(string pos)
{
var pos = "1; 2; 3";
List<string> result = pos.Split(';').ToList();
}
public void Opis(string des)
{
var des = "aaa; bbb; ccc";
List<string> result = des.Split(';').ToList();
}
public void Ilosc(string pcs)
{
var pcs = "1; 2; 3";
List<string> result = pcs.Split(';').ToList();
}
}
Sorry for my english, I tried my best! :)
Here is a sample that produces your desired xml:
var pos = "1; 2; 3";
var des = "aaa; bbb; ccc";
var pcs = "1.000; 44.000; 65.000";
var posList = pos.Split(';').ToList();
var desList = des.Split(';').ToList();
var pcsList = pcs.Split(';').ToList();
var sb = new StringBuilder();
using (var xw = XmlWriter.Create(sb, new XmlWriterSettings { OmitXmlDeclaration = true }))
{
var ns = "http://www.example.com";
var prefix = "urn";
xw.WriteStartElement(prefix, "LINES", ns);
for (int i = 0; i < posList.Count; i++)
{
xw.WriteStartElement(prefix, "RECEIVE_EINVOICE_LINE", ns);
xw.WriteElementString(prefix, "C00", ns, posList[i]);
xw.WriteElementString(prefix, "C14", ns, desList[i]);
xw.WriteElementString(prefix, "D00", ns, pcsList[i]);
xw.WriteEndElement();
}
xw.WriteEndElement();
}
var soapMessage = sb.ToString();

CreateNewCheckBox with Text from XML

I'm kinda stuck with reading the value of a xml-file.
The XML looks like:
<?xml version="1.0" encoding="utf-16"?>
<spfFiles>
<file>200_006 xxxxxxx</file>
<file>200_010 xxxxxxx</file>
<file>200_022 xxxxxxx</file>
<file>200_023 xxxxxxx</file>
<file>200_024 xxxxxxx</file>
<file>200_031 xxxxxxx</file>
<file>200_041 xxxxxxx</file>
</spfFiles>
What I'm trying to do is that I want to creat a new Checkbox for each file.
XmlTextReader xReader = new XmlTextReader("spfFiles_simW.xml");
while (xReader.Read())
{
switch (xReader.NodeType)
{
case XmlNodeType.Text: //Display the text in each element.
pnlSPFLIST.Controls.Add(CreateNewCheckBox(xReader.Value));
break;
}
}
The creation of each new element works fine. But I've got trouble with the file names. Each Checkbox only gets the part before the space as a name. For example "200_006". My xmlReader somehow seems to cut the rest of.
Edit:
So here is my CreateNewCheck
private CheckBox CreateNewCheckBox(string sName)
{
label1.Text = sName;
int iExistingCheckBoxX = 0;
int iExistingCheckBoxY = 0;
int iIncrementX = 100;
int iIncrementY = 20;
CheckBox cbNew = new CheckBox();
cbNew.Width = iIncrementX;
if (pnlSPFLIST.Controls.Count == 0)
{
cbNew.Location = new Point(pnlSPFLIST.Location.X, pnlSPFLIST.Location.Y-25);
}
else
{
// Existing checkboxes, so get the Location of the last one.
iExistingCheckBoxX = pnlSPFLIST.Controls[pnlSPFLIST.Controls.Count - 1].Location.X;
iExistingCheckBoxY = pnlSPFLIST.Controls[pnlSPFLIST.Controls.Count - 1].Location.Y;
iExistingCheckBoxX = pnlSPFLIST.Location.X;
iExistingCheckBoxY = iExistingCheckBoxY + iIncrementY + 10;
cbNew.Location = new Point(iExistingCheckBoxX, iExistingCheckBoxY);
}
// Set the Text property according to the input.
cbNew.Text = sName;
return cbNew;
}
Does anyone know where I've gone wrong?
So here is the right solution.
I Just had to change my CreateNewCheckBox-Method:
private CheckBox CreateNewCheckBox(string sName)
{
...
int iIncrementX = 300;
int iIncrementY = 20;
...
}
Just increase the X-Value and everything works fine.

Categories

Resources