save separate separate xml file base on orderid - c#

Hi all currently i have saved all the xml file in one file . but i need to save in separate file. could you please help me on it.
current code :-
System.Data.DataTable checkFile = new System.Data.DataTable();
sql = "sql";
DBCon clsDB = new DBCon(SAPCompanySettings.MSSQLConnectionString);
clsDB.Execute(sql, ref checkFile);
var stringwriter = new StringWriter();
using (var xmlWriter = XmlWriter.Create(stringwriter, new XmlWriterSettings { Indent = true }))
{
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement("Root");
var groups = checkFile.AsEnumerable().GroupBy(x => new { DocNum = x.Field<int>("orderid"), Type = x.Field<string>("Type"), Status = x.Field<string>("Status"), productno = x.Field<string>("productno"), ProductDescription = x.Field<string>("ProductDescription"), uom = x.Field<string>("uom"), customer = x.Field<string>("customer"), remark = x.Field<string>("remark"), U_JobNumber = x.Field<string>("U_JobNumber"), U_SalesPerson = x.Field<string>("U_SalesPerson"), U_JobType = x.Field<string>("U_JobType"), PlannedQty = x.Field<decimal>("PlannedQty"), OriginNum = x.Field<int?>("OriginNum"), orderdate = x.Field<DateTime>("orderdate"), duedate = x.Field<DateTime>("duedate") });
foreach (var group in groups)
{
xmlWriter.WriteStartElement("productionorder");
xmlWriter.WriteAttributeString("orderid", group.Key.DocNum.ToString());
xmlWriter.WriteElementString("type", group.Key.Type);
xmlWriter.WriteElementString("status", group.Key.Status);
xmlWriter.WriteElementString("productno", group.Key.productno); xmlWriter.WriteElementString("ProductDescription", group.Key.ProductDescription);
xmlWriter.WriteElementString("PlannedQty",group.Key.PlannedQty.ToString());
xmlWriter.WriteElementString("uom", group.Key.uom);
xmlWriter.WriteElementString("salesorder", group.Key.OriginNum.ToString()); xmlWriter.WriteElementString("customer", group.Key.customer);
xmlWriter.WriteElementString("Remarks", group.Key.remark);
xmlWriter.WriteStartElement("date");
xmlWriter.WriteElementString("orderdate", group.Key.orderdate.ToString());
xmlWriter.WriteElementString("duedate", group.Key.duedate.ToString());
xmlWriter.WriteEndElement();
xmlWriter.WriteElementString("jobdescription", group.Key.U_JobNumber);
xmlWriter.WriteElementString("salesperson", group.Key.U_SalesPerson);
xmlWriter.WriteElementString("jobtype", group.Key.U_JobType);
foreach (DataRow row in group)
{
xmlWriter.WriteStartElement("Components");
xmlWriter.WriteElementString("itemno", row.Field<string>("itemno"));
xmlWriter.WriteEndElement();
}
xmlWriter.WriteEndElement();
var sql2 = "update IS_XML_generated='Y' from OWOR where DocNum=group.Key.DocNum";
clsDB.Execute(sql2);
}
xmlWriter.WriteEndElement();
}
var xml = stringwriter.ToString();
XmlDocument docSave = new XmlDocument();
docSave.LoadXml(stringwriter.ToString());
docSave.Save(System.IO.Path.Combine(#"C:\DEMO PSL\DOXMLFILE", "Filename.xml"));
Current output:-
filename.xml:-both order is saved in same file
<?xml version="1.0" encoding="utf-16"?>
<Root>
<productionorder orderid="1">
...................
</productionorder>
<productionorder orderid="2">
...............
</productionorder>
</Root>
but expected output :-i need to save different different file
1.xml :-
<?xml version="1.0" encoding="utf-16"?>
<Root>
<productionorder orderid="1">
..............
</productionorder>
</Root>
2.xml :-
<?xml version="1.0" encoding="utf-16"?>
<Root>
<productionorder orderid="2">
............
</productionorder>
</Root>

I swapped the using and the foreach loops. I also modify filename so each filename is unique.
System.Data.DataTable checkFile = new System.Data.DataTable();
sql = "sql";
DBCon clsDB = new DBCon(SAPCompanySettings.MSSQLConnectionString);
clsDB.Execute(sql, ref checkFile);
var groups = checkFile.AsEnumerable().GroupBy(x => new { DocNum = x.Field<int>("orderid"), Type = x.Field<string>("Type"), Status = x.Field<string>("Status"), productno = x.Field<string>("productno"), ProductDescription = x.Field<string>("ProductDescription"), uom = x.Field<string>("uom"), customer = x.Field<string>("customer"), remark = x.Field<string>("remark"), U_JobNumber = x.Field<string>("U_JobNumber"), U_SalesPerson = x.Field<string>("U_SalesPerson"), U_JobType = x.Field<string>("U_JobType"), PlannedQty = x.Field<decimal>("PlannedQty"), OriginNum = x.Field<int?>("OriginNum"), orderdate = x.Field<DateTime>("orderdate"), duedate = x.Field<DateTime>("duedate") });
int count = 1;
foreach (var group in groups)
{
var stringwriter = new StringWriter();
using (var xmlWriter = XmlWriter.Create(stringwriter, new XmlWriterSettings { Indent = true }))
{
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement("Root");
xmlWriter.WriteStartElement("productionorder");
xmlWriter.WriteAttributeString("orderid", group.Key.DocNum.ToString());
xmlWriter.WriteElementString("type", group.Key.Type);
xmlWriter.WriteElementString("status", group.Key.Status);
xmlWriter.WriteElementString("productno", group.Key.productno); xmlWriter.WriteElementString("ProductDescription", group.Key.ProductDescription);
xmlWriter.WriteElementString("PlannedQty",group.Key.PlannedQty.ToString());
xmlWriter.WriteElementString("uom", group.Key.uom);
xmlWriter.WriteElementString("salesorder", group.Key.OriginNum.ToString()); xmlWriter.WriteElementString("customer", group.Key.customer);
xmlWriter.WriteElementString("Remarks", group.Key.remark);
xmlWriter.WriteStartElement("date");
xmlWriter.WriteElementString("orderdate", group.Key.orderdate.ToString());
xmlWriter.WriteElementString("duedate", group.Key.duedate.ToString());
xmlWriter.WriteEndElement();
xmlWriter.WriteElementString("jobdescription", group.Key.U_JobNumber);
xmlWriter.WriteElementString("salesperson", group.Key.U_SalesPerson);
xmlWriter.WriteElementString("jobtype", group.Key.U_JobType);
foreach (DataRow row in group)
{
xmlWriter.WriteStartElement("Components");
xmlWriter.WriteElementString("itemno", row.Field<string>("itemno"));
xmlWriter.WriteEndElement();
}
xmlWriter.WriteEndElement();
var sql2 = "update IS_XML_generated='Y' from OWOR where DocNum=group.Key.DocNum";
clsDB.Execute(sql2);
xmlWriter.WriteEndElement();
}
var xml = stringwriter.ToString();
XmlDocument docSave = new XmlDocument();
docSave.LoadXml(stringwriter.ToString());
docSave.Save(System.IO.Path.Combine(#"C:\DEMO PSL\DOXMLFILE", "Filename" + count.ToString() + ".xml"));
count++;
}

Related

Missing Schema Info

I am getting this error message n Visual Studio: "Could not find Schema Information Number, Name, Period, a0 and aJ." I have a working schema "SemiMajorAxis.xsd" but I do not know how to use it. Later in the program I deal with the DataTable
SemiMajorAxis.aspx.cs
DataSet dsread = new DataSet();
DataTable dtread = new DataTable();
dsread.ReadXml(Server.MapPath("SemiMajorAxis.xml"));
dtread = dsread.Tables[0];
XDocument xmldoc = XDocument.Load(Server.MapPath("SemiMajorAxis.xml"));
var elements = from data in xmldoc.Descendants("planet")
select new
{
Numberp = (int)data.Element("Number"),
Namep = (string)data.Element("Name"),
Pyrsp = (double)data.Element("Period"),
a0p = (double)data.Element("a0"),
aJp = (double)data.Element("aJ")
};
foreach (var element in elements)
{
m = m + 1;
num[m] = element.Numberp;
name[m] = element.Namep;
a0[m] = element.a0p;
aJ[m] = element.aJp;
a[m] = a0[m] + aJ[m] * J;
}
SemiMajorAxis.xml
<?xml version="1.0" standalone="yes"?>
<planets>
<planet>
<Number>1</Number>
<Name>Mercury</Name>
<Period>0.2408</Period>
<a0>0.38709893</a0>
<aJ>0.00000066</aJ>
</planet>
<planet>
<Number>2</Number>
<Name>Venus</Name>
<Period>0.6152</Period>
<a0>0.72333199</a0>
<aJ>0.00000092</aJ>
</planet>
<planet>
<Number>3</Number>
<Name>Earth</Name>
<Period>1</Period>
<a0>1.00000011</a0>
<aJ>-0.00000005</aJ>
</planet>
</planets>

XML generation using c#

My goal is to generate xml structure in this format
<?xml version='1.0' encoding='UTF-8'?>
<return xmlns:rmas="value here" xmlns:xsi="value here" xsi:noNamespaceSchemaLocation="value here">
<header>
<return-code>""</return-code>
<return-desc>""</return-desc>
<as-at-date>""</as-at-date>
<operator-code>""</operator-code>
</header>
<body>
<scheme>
<code>10050</code>
<employer>
<empr-code></empr-code>
<data>
<serial-no />
<pin />
<employer-contribution />
<employee-contribution />
<voluntary-contribution />
<total-contribution />
</data>
</employer>
</scheme>
<scheme>
<code>10100</code>
<employer>
<empr-code></empr-code>
<data>
<serial-no />
<pin />
<employer-contribution />
<employee-contribution />
<voluntary-contribution />
<total-contribution />
</data>
</employer>
</scheme>
[...]
</body>
</return>
This is the sample of the data I am consuming
scheme-code emp-code pin empr-contr empyee-contr total total-vol-cont
10050 PR0000395010 PEN200386572133 54777.28 43821.82 108599.1 10000
10050 PR0000679771 PEN200629902715 65528.34 0 215528.34 150000
10050 PR0000007340 PEN200629902715 0 65528.34 215528.34 150000
10050 PU000035E001 PEN100786299723 10570.34 10570.34 21140.68 0
10050 TCF000615630 PEN100786299723 12060.15 12060.16 24120.31 0
10050 TCF000615630 PEN100786299723 12204.98 12204.99 24409.97 0
10050 PR0000615630 PEN100144364216 10945.19 13681.49 24626.68 0
10050 PR0000615630 PEN100453089112 14319.32 17899.15 32218.47 0
10050 PR0000615630 PEN200742682512 13116.33 16395.41 29511.74 0
10100 PRTEMP005022 PEN100940140007 792 990 1782 0
10100 PRTEMP005022 PEN100799131715 2375 2970 5345 0
10100 PRTEMP005022 PEN100799212715 831.6 1039.5 1871.1 0
In the body tag, I'd like to group the data first by the scheme-code and inside the code, group the data by the emp-code in that scheme and then by the data(pin, empr-contr,empyee-contr...) having the empr-code. The serial-no(int) for each data tag will be 0,1,2,3....T999 depending on the number of data tags in the parent employer tag. Please see further example below
<scheme>
<code>10050</code>
[...]
<employer>
<empr-code>PR0000615630</empr-code>
<data>
<serial-no>1</serial-no>
<pin>PEN100144364216</pin>
<employer-contribution>10945.19</employer-contribution>
<employee-contribution>13681.49</employee-contribution>
<voluntary-contribution>0.00</voluntary-contribution>
<total>32218.47</total>
</data>
<data>
<serial-no>2</serial-no>
<pin>PEN100453089112</pin>
<employer-contribution>14319.32</employer-contribution>
<employee-contribution>17899.15/employee-contribution>
<voluntary-contribution>0.00</voluntary-contribution>
<total>32218.47</total>
</data>
<data>
<serial-no>T9999</serial-no>
<pin>PEN200742682512</pin>
<employer-contribution>13116.33</employer-contribution>
<employee-contribution>16395.41</employee-contribution>
<voluntary-contribution>0.00</voluntary-contribution>
<total>29511.74</total>
</data>
</employer>
[...]
</scheme>
How can I generate it using XMLDocument or XMLWriter
Try following xml linq. I put your input file into a text file and then read into DataTable. Then create XML from table :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string INPUT_FILENAME = #"c:\temp\test.txt";
const string OUTPUT_FILENAME = #"c:\temp\test.xml";
static DataTable dt = new DataTable();
static XDocument doc;
static void Main(string[] args)
{
ReadData(INPUT_FILENAME);
dt = dt.AsEnumerable()
.OrderBy(x => x.Field<string>("scheme-code"))
.ThenBy(x => x.Field<string>("emp-code"))
.ThenBy(x => x.Field<string>("pin"))
.CopyToDataTable();
CreateXml();
doc.Save(OUTPUT_FILENAME);
}
static void ReadData(string filename)
{
int rowNumber = 0;
string line = "";
StreamReader reader = new StreamReader(INPUT_FILENAME);
while ((line = reader.ReadLine()) != null)
{
string[] splitData = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
if (++rowNumber == 1)
{
for (int i = 0; i < splitData.Length; i++)
{
if (i < 3)
{
dt.Columns.Add(splitData[i], typeof(string));
}
else
{
dt.Columns.Add(splitData[i], typeof(decimal));
}
}
}
else
{
DataRow newRow = dt.Rows.Add();
for (int i = 0; i < splitData.Length; i++)
{
if (i < 3)
{
newRow[i] = splitData[i];
}
else
{
newRow[i] = decimal.Parse(splitData[i]);
}
}
}
}
reader.Close();
}
static void CreateXml()
{
string xmlns_rmas = "value here";
string xmlns_xsi = "value here";
string xmlns_noNamespaceSchemaLocation = "value here";
string xmlIdentFormat =
"<?xml version='1.0' encoding='UTF-8'?>" +
"<return" +
" xmlns:rmas=\"{0}\"" +
" xmlns:xsi=\"{1}\"" +
" xsi:noNamespaceSchemaLocation=\"{2}\">" +
"</return>";
string xmlIdent = string.Format(xmlIdentFormat, xmlns_rmas, xmlns_xsi, xmlns_noNamespaceSchemaLocation);
doc = XDocument.Parse(xmlIdent);
XElement _return = doc.Root;
string returnCode = "";
string returnDesc = "";
DateTime date = DateTime.Now;
string operatorCode = "";
XElement header = new XElement("header", new object[] {
new XElement("return-code", returnCode),
new XElement("return-desc", returnDesc),
new XElement("as-at-date", date),
new XElement("operator-code", operatorCode)
});
_return.Add(header);
XElement body = new XElement("body");
_return.Add(body);
foreach(var schemeGroup in dt.AsEnumerable().GroupBy(x => x.Field<string>("scheme-code")))
{
XElement scheme = new XElement("scheme");
body.Add(scheme);
XElement code = new XElement("code", schemeGroup.Key);
scheme.Add(code);
foreach(var empCodeGroup in schemeGroup.GroupBy(y => y.Field<string>("emp-code")))
{
XElement employer = new XElement("employer");
scheme.Add(employer);
int serialNumber = 0;
foreach(var pinGroup in empCodeGroup.GroupBy(y => y.Field<string>("pin")))
{
if (serialNumber == 0)
{
XElement emprCode = new XElement("empr-code", empCodeGroup.Key);
employer.Add(emprCode);
}
foreach (DataRow row in pinGroup)
{
XElement data = new XElement("data");
employer.Add(data);
if ((empCodeGroup.Count() > 1) && (serialNumber == empCodeGroup.Count() - 1))
{
data.Add(new XElement("serial-no", "T999"));
}
else
{
data.Add(new XElement("serial-no", serialNumber));
}
data.Add(new XElement("pin", pinGroup.Key));
data.Add(new XElement("employer-contribution", row.Field<decimal>("empr-contr")));
data.Add(new XElement("employee-contribution", row.Field<decimal>("empyee-contr")));
data.Add(new XElement("voluntary-contribution", row.Field<decimal>("total-vol-cont")));
data.Add(new XElement("total-contribution", row.Field<decimal>("total")));
serialNumber++;
}
}
}
}
}
}
}
Load Data to the DataSet and use Write XML. This is the simplest way you can try
DataSet oDsData = new DataSet();
oDsData.WriteXml("path", XmlWriteMode.WriteSchema);
This could be one of the solution if your data is in MSSQL server. I assumed your data resides in a table (##tmp_test) in database.
public string GetXML()
{
XmlDocument document = new XmlDocument();
XmlDeclaration xmlDeclaration = document.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = document.DocumentElement;
document.InsertBefore(xmlDeclaration, root);
var returnElement = document.CreateElement( "return");
returnElement.SetAttribute("xmlns:rmas", "value here");
returnElement.SetAttribute("xmlns:xsi", "value here");
returnElement.SetAttribute("noNamespaceSchemaLocation", "value here");
var header = document.CreateElement("header");
var rc = document.CreateElement("return-code");
rc.InnerText = "\"\"";
header.AppendChild(rc);
var rd = document.CreateElement("return-desc");
rd.InnerText = "\"\"";
header.AppendChild(rd);
var aad = document.CreateElement("as-at-date");
aad.InnerText = "\"\"";
header.AppendChild(aad);
var oc = document.CreateElement("operator-code");
oc.InnerText = "\"\"";
header.AppendChild(oc);
returnElement.AppendChild(header);
var body = document.CreateElement("body");
body.InnerXml = GetBodyXML();
returnElement.AppendChild(body);
document.AppendChild(returnElement);
return document.OuterXml;
}
private string GetBodyXML()
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandText = #"
SELECT 1 AS Tag
,NULL AS Parent
,[Scheme].[scheme-code] AS [scheme!1!code!ELEMENT]
,NULL AS [employer!2!empr-code!ELEMENT]
,NULL AS [data!3!serial-no!ELEMENT]
,NULL AS [data!3!pin!ELEMENT]
,NULL AS [data!3!employer-contribution!ELEMENT]
,NULL AS [data!3!employee-contribution!ELEMENT]
,NULL AS [data!3!voluntary-contribution!ELEMENT]
,NULL AS [data!3!total!ELEMENT]
FROM ##tmp_test [Scheme]
UNION
SELECT 2 AS Tag
,1 AS Parent
,[Scheme].[scheme-code] AS code
,[Scheme].[emp-code] AS [empr-code]
,NULL AS [serial-no]
,NULL AS pin
,NULL AS [employer-contribution]
,NULL AS [employee-contribution]
,NULL AS [voluntary-contribution]
,NULL AS [total]
FROM ##tmp_test [Scheme]
UNION
SELECT 3 AS Tag
,2 AS Parent
,[Scheme].[scheme-code] AS code
,[Scheme].[emp-code] AS [empr-code]
,ROW_NUMBER() OVER (
PARTITION BY [Scheme].[scheme-code]
,[Scheme].[emp-code] ORDER BY pin
) AS [serial-no]
,[Scheme].pin AS [pin]
,[Scheme].[empr-contr] AS [employer-contribution]
,[Scheme].[empyee-contr] AS [employee-contribution]
,[Scheme].[total-vol-cont] AS [voluntary-contribution]
,[Scheme].total AS [total]
FROM ##tmp_test [Scheme]
ORDER BY [scheme!1!code!ELEMENT]
,[employer!2!empr-code!ELEMENT]
FOR XML EXPLICIT
";
//Better approach to read all xml - https://stackoverflow.com/a/40775242/1010395
using (XmlReader xmlReader = command.ExecuteXmlReader())
{
XPathDocument xp = new XPathDocument(xmlReader);
XPathNavigator xn = xp.CreateNavigator();
return xn.OuterXml;
}
}
}
}

Appending an existing XML file with XmlWriter

I've used the following code to create an XML file:
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.NewLineOnAttributes = true;
using (XmlWriter xmlWriter = XmlWriter.Create("Test.xml", xmlWriterSettings))
{
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement("School");
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
xmlWriter.Close();
}
I need to insert nodes dynamically creating the following structure:
<?xml version="1.0" encoding="utf-8"?>
<School />
<Student>
<FirstName>David</FirstName>
<LastName>Smith</LastName>
</Student>
...
<Teacher>
<FirstName>David</FirstName>
<LastName>Smith</LastName>
</Teacher>
...
</School>
How can I do it? The values of "FirstName" and "LastName" should be read from the keyboard and the values ​​can be entered at any time, of course under existing.
you can use Linq Xml
XDocument doc = XDocument.Load(xmlFilePath);
XElement school = doc.Element("School");
school.Add(new XElement("Student",
new XElement("FirstName", "David"),
new XElement("LastName", "Smith")));
doc.Save(xmlFilePath);
Edit
if you want to add Element to Existing <Student>, just add an Attribute before
school.add(new XElement("Student",
new XAttribute("ID", "ID_Value"),
new XElement("FirstName", "David"),
new XElement("LastName", "Smith")));
Then you can add further Details to the Existing <Student> by search -> get -> add
XElement particularStudent = doc.Element("School").Elements("Student")
.Where(student => student.Attribute("ID").Value == "SearchID")
.FirstOrDefault();
if(particularStudent != null)
particularStudent.Add(new XElement("<NewElementName>","<Value>");
finally I succeeded :)
if (!File.Exists("Test.xml"))
{
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.NewLineOnAttributes = true;
using (XmlWriter xmlWriter = XmlWriter.Create("Test.xml", xmlWriterSettings))
{
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement("School");
xmlWriter.WriteStartElement("Student");
xmlWriter.WriteElementString("FirstName", firstName);
xmlWriter.WriteElementString("LastName", lastName);
xmlWriter.WriteEndElement();
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
xmlWriter.Flush();
xmlWriter.Close();
}
}
else
{
XDocument xDocument = XDocument.Load("Test.xml");
XElement root= xDocument.Element("School");
IEnumerable<XElement> rows = root.Descendants("Student");
XElement firstRow= rows.First();
firstRow.AddBeforeSelf(
new XElement("Student",
new XElement("FirstName", firstName),
new XElement("LastName", lastName)));
xDocument.Save("Test.xml");
}
Let me give you a suggestion. When you creating your xml file, give an unique id to your students like this:
// to store the id variable, if you create more than one student you can increase it
count = 0;
xmlWriter.WriteStartElement("School");
xmlWriter.WriteAttributeString("ID",count.ToString());
xmlWriter.WriteEndElement();
Then when you need to add information to this student you can get ID,Firstname and Lastname and you can edit your XML file with LINQ to XML like this:
int id = Convert.ToInt32(txtStudentId.Text);
XDocument xDoc = XDocument.Load("Test.xml");
XElement student = xDoc.Descendants("Student").Where(x => (string) x.Attribute("ID") == id).FirstOrDefault();
if (student != null)
{
string firstName = txtFirstName.Text;
string lastName = txtLastName.Text;
XElement first = new XElement("FirstName", firstName);
XElement last = new XElement("LastName", lastName);
student.Add(first);
student.Add(last);
xDoc.Save("Test.xml");
}
I have a suggestion for the next time:
string nameFile = "Test.xml";
bool newFile = false;
if (!File.Exists(nameFile))
{
newFile = true;
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.NewLineOnAttributes = true;
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement("School");
xmlWriter = XmlWriter.Create("Test.xml", xmlWriterSettings))
}
else
{
doc = new XmlDocument();
doc.Load(nameFile);
// Create a XPathNavigator
// You can go where you want to add
// In this case it is just after last child of the roor
XPathNavigator navigator = doc.CreateNavigator();
navigator.MoveToChild("School", "");
xmlWriter = navigator.AppendChild();
}
// From here you can work only with xmlWriter,
// One will point on a file and the other on the stream of xmlDocument
// So you will need to save the document in the second choise
xmlWriter.WriteStartElement("Student");
xmlWriter.WriteElementString("FirstName", firstName);
xmlWriter.WriteElementString("LastName", lastName);
xmlWriter.WriteEndElement();
// End document / close or save.
if (newFile)
xmlWriter.WriteEndDocument();
xmlWriter.Close();
if (!newFile)
doc.Save(nameFile);
It should work. :)
I know you asked for XmlWriter, but I believe you can achieve this using less code with XDocument. Here is my solution:
var filePath = "path/XmlFile.xml";
var xmlDoc = XDocument.Load(filePath);
var parentElement = new XElement("Student");
var firstNameElement = new XElement("FirstName", firstNameVariable);
var lastNameElement = new XElement("LastName", lastNameVariable);
parentElement.Add(firstNameElement);
parentElement.Add(lastNameElement);
var rootElement = xmlDoc.Element("School");
rootElement?.Add(parentElement);
xmlDoc.save();
This is based on the following XML structure and will append at ... :
<School>
<Student>
<FirstName>John</FirstName>
<LastName>Johnson</LastName>
</Student>
...
</School>
Hope this helps!

Get actual Column name from XML

I have a problem with this XML. In our system we are using XML from DataSet (ds.GetXml()) and send it to our Silverlight application as a string. From there we read the XML with the following:
StringReader stream = new StringReader(XmlData);
XmlReader reader = XmlReader.Create(stream);
XDocument myDoc = new XDocument();
myDoc = XDocument.Load(reader);
The problem: Some times column names are changed, example: If a column name starts with a numeric number then it will convert it.
"_x0033_column" original column name was "3column"
Is it possible to get the original column name from the XML?
The XML
<NewDataSet>
<Table>
<CheckboxCol>0</CheckboxCol>
<Kunde>1</Kunde>
<Ort_x0020_Postfach />
<erfasst_x0020_von>MasterMind</erfasst_x0020_von>
<Buchhaltungsnummer>1</Buchhaltungsnummer>
<Kreditlimit>0.0000</Kreditlimit>
<_x0033_STT_Inaktiv>Nein</_x0033_STT_Inaktiv>
<_x0033_STT_Status>Interessent</_x0033_STT_Status>
<Zahlungsbedingungen>10 : 10 Tage Netto</Zahlungsbedingungen>
</Table>
<Table>
<CheckboxCol>0</CheckboxCol>
<Kunde>3</Kunde>
<Ort_x0020_Postfach />
<erfasst_x0020_von>MasterMind</erfasst_x0020_von>
<Buchhaltungsnummer>3</Buchhaltungsnummer>
<Kreditlimit>0.0000</Kreditlimit>
<_x0033_STT_Inaktiv>Nein</_x0033_STT_Inaktiv>
<_x0033_STT_Status>Kunde</_x0033_STT_Status>
<Zahlungsbedingungen>10 : 10 Tage Netto</Zahlungsbedingungen>
</Table>
<NewDataSet>
My current Code
public SLDataTable(string XmlData, Dictionary<string, string> ColumnDict)
{
ColumnDefination = ColumnDict;
foreach (var Item in ColumnDefination)
{
Columns.Add(new SLDataColumn() { ColumnName = Item.Key.ToString().Trim(), DataType = GetNullableType(GetColumnType(Item.Value.ToString())) });
}
StringReader stream = new StringReader(XmlData);
XmlReader reader = XmlReader.Create(stream);
XDocument myDoc = new XDocument();
myDoc = XDocument.Parse(XmlData);
if (myDoc != null && myDoc.Elements().Count() > 0 && myDoc.Element("NewDataSet").Elements().Count() > 0)
{
int columnCount = myDoc.Element("NewDataSet").Element("Table").Elements().Count();
int rowCount = myDoc.Element("NewDataSet").Elements().Count();
string ElmentColumnName = string.Empty;
foreach (XElement element in myDoc.Element("NewDataSet").Elements())
{
var row = new SLDataRow(this);
foreach (XElement ele in element.Elements())
{
ElmentColumnName = ele.Name.ToString().Replace("_x0020_", " ").Replace("_x0028_", " (").Replace("_x0029_", ") ");
row[ElmentColumnName] = ConvertValue(ElmentColumnName, ele.Value);
}
Rows.Add(row);
}
}
}

Help with Linq to XML

Iv got two DB tables. One containing types(Id, Name) and the other holds datapoints (RefId, Date, Value) that are referenced by the types. I need to create a XML file with the following strukture:
<?xml version='1.0' encoding='utf-8' ?>
<root>
<type>
<name></name>
<data>
<date></date>
<temp></temp>
</data>
<data>
<date></date>
<temp></temp>
</data>
<data>
<date></date>
<temp></temp>
</data>
</type>
</root>
And iv got the following code to do this
public XmlDocument HelloWorld()
{
string tmp = "";
try
{
sqlConn.ConnectionString = ConfigurationManager.ConnectionStrings["NorlanderDBConnection"].ConnectionString;
DataContext db = new DataContext(sqlConn.ConnectionString);
Table<DataType> dataTypes = db.GetTable<DataType>();
Table<DataPoints> dataPoints = db.GetTable<DataPoints>();
var dataT =
from t in dataTypes
select t;
var dataP =
from t in dataTypes
join p in dataPoints on t.Id equals p.RefId
select new
{
Id = t.Id,
Name = t.Name,
Date = p.PointDate,
Value = p.PointValue
};
string xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><root></root>";
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(xmlString);
int count = 0;
foreach (var dt in dataT)
{
XmlElement type = xmldoc.CreateElement("type");
XmlElement name = xmldoc.CreateElement("name");
XmlNode nameText = xmldoc.CreateTextNode(dt.Name);
name.AppendChild(nameText);
type.AppendChild(name);
foreach(var dp in dataP.Where(dt.Id = dp.RefId))
{
XmlElement data = xmldoc.CreateElement("data");
XmlElement date = xmldoc.CreateElement("date");
XmlElement temp = xmldoc.CreateElement("temp");
XmlNode dateValue = xmldoc.CreateTextNode(dp.Date.ToString());
date.AppendChild(dateValue);
XmlNode tempValue = xmldoc.CreateTextNode(dp.Value.ToString());
temp.AppendChild(tempValue);
data.AppendChild(date);
data.AppendChild(temp);
type.AppendChild(data);
}
xmldoc.DocumentElement.AppendChild(type);
}
return xmldoc;
}
catch(Exception e)
{
tmp = e.ToString();
}
return null;
}
[Table(Name="DataTypes")]
public class DataType
{
[Column(IsPrimaryKey = true)]
public long Id;
[Column]
public string Name;
}
[Table(Name="DataPoints")]
public class DataPoints
{
[Column]
public long RefId;
[Column]
public DateTime PointDate;
[Column]
public double PointValue;
}
This is not a working code. Im having problems with LINQ and the inner joins. Could someone please help me to get the correct strukture. I hope its kinda clear what im trying to achive.
Best Regards
Marthin
var result =
new XDocument(new XElement("root",
from dt in dataTypes
join dp in dataPoints on dt.Id equals dp.RefId
select new XElement("type",
new XElement("name", dt.Name),
new XElement("data",
new XElement("date", dp.PointDate),
new XElement("temp", dp.PointValue)))));
var result =
new XDocument(new XElement("root",
from dt in dataTypes
select new XElement("type",
new XElement("name", dt.Name),
from dp in dataPoints
where dp.RefId == dt.Id
select new XElement("data",
new XElement("date", dp.PointDate),
new XElement("temp", dp.PointValue)))));

Categories

Resources