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
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>
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;
}
}
}
}
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!
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);
}
}
}
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)))));