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 want to iterate the data from XMLElement. In List i have 10 row of records . each row contains again list of values. In row, each values need to store into somString type.
Below is the XMLElement getting from List
<ROW id="1">
<D n="6721">10128</D>
<D n="6724">CL</D>
<D n="6771">*</D>
<D n="6773">ACT</D>
<D n="6774">PHON</D>
<D n="6775">04-MAR-2018 21:54</D>
<D n="6779">MEP-IU</D>
<D n="6780">MEP-IU-010</D>
<D n="6782">CWP2B19-113</D>
<D n="6792">11410</D>
<D n="6809"/>
<D n="6880"/>
<D n="11651">Tap is not working in the Back of the Apt
Name: Alex
Contact : 971-566826978</D>
<D n="100410">40977</D>
<D n="101312">AHMED.ALI#MERAAS.AE</D>
<D n="101313">HANDOVER</D>
</ROW>
I tried this code for i tried to iterating data, but i m getting very 1st element only not remaining elements:
for (int i = 0; i < nodeList.Count; i++)
{
if (nodeList[i].InnerText.Length > 0)
{
string name =(string) i.FirstChild.Value;
MessageBox.Show(nodeList[i].InnerText);
}
}
But i m getting filed column value only .. how to get remaining data from XMLElement.
In List i have 10 row of records . each row contains again list of values. In row, each values need to store into somString type.
I want to extract list of all records from response. I m not sure how to go about writing a code for to filter the data.
Kindly refer some sample for this one.
Here is a quick and dirty way to get at the values, this can be improved by removing the hard-coded values and checking for objects prior to accessing them.
EDIT: XML structure is from here.
using (var stream = new StreamReader("Response.xml"))
{
XDocument doc = XDocument.Load(stream);
var nodes = doc.Elements().Descendants()
.Where(x => x.Name == XName.Get("ROW", "http://schemas.datastream.net/MP_functions/MP0118_GetGridHeaderData_001_Result"));
foreach (var node in nodes)
{
if (node.FirstAttribute != null)
{
var firstAttribute = node.FirstAttribute;
Console.WriteLine($"{firstAttribute.Name.LocalName} - {firstAttribute.Value}");
var children = node.Descendants();
if (children.Count() > 0)
{
foreach (var child in children)
{
Console.WriteLine($"{child.FirstAttribute.Value}:{child.Value}");
}
}
Console.WriteLine("----------------------------------");
}
}
}
using (WebResponse response = httpWebRequest.GetResponse())
{
using (StreamReader streamreader = new StreamReader(response.GetResponseStream()))
{
string result1 = streamreader.ReadToEnd();
MessageBox.Show(result1);
xmlDocument = new XmlDocument();
xmlDocument.LoadXml(result1);
XmlNodeList nodeList;
if (xmlDocument.DocumentElement.Attributes["xmlns:soapenv"] != null)
{
string xmlns = xmlDocument.DocumentElement.Attributes["xmlns:soapenv"].Value;
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);
nsmgr.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
nsmgr.AddNamespace("df", "http://schemas.datastream.net/MP_functions/MP0118_GetGridHeaderData_001_Result");
nodeList = xmlDocument.SelectNodes("/soapenv:Envelope/soapenv:Body/df:MP0118_GetGridHeaderData_001_Result/df:GRIDRESULT/df:GRID/df:DATA/df:ROW[*]", nsmgr);
}
else
{
nodeList = xmlDocument.SelectNodes("/soapenv:Envelope/soapenv:Body/df:MP0118_GetGridHeaderData_001_Result/df:GRIDRESULT/df:GRID/df:DATA/df:ROW[*]");
}
for (int i = 0; i < nodeList.Count; i++)
{
if (nodeList[i].InnerText.Length > 0)
{
String ctr_code = nodeList[i].ChildNodes[0].InnerText;
String ctr_status = nodeList[i].ChildNodes[1].InnerText;
String ctr_org = nodeList[i].ChildNodes[2].InnerText;
String ctr_type = nodeList[i].ChildNodes[3].InnerText;
String ctr_contactsource = nodeList[i].ChildNodes[4].InnerText;
String ctr_created = nodeList[i].ChildNodes[5].InnerText;
String ctr_servicecategory = nodeList[i].ChildNodes[6].InnerText;
String ctr_serviceproblem = nodeList[i].ChildNodes[7].InnerText;
String ctr_object = nodeList[i].ChildNodes[8].InnerText;
String ctr_contactinfoid = nodeList[i].ChildNodes[9].InnerText;
String ctr_contactnote = nodeList[i].ChildNodes[10].InnerText;
String ctr_desc = nodeList[i].ChildNodes[11].InnerText;
String ctr_note = nodeList[i].ChildNodes[12].InnerText;
String ctr_event = nodeList[i].ChildNodes[13].InnerText;
String ctr_createdby = nodeList[i].ChildNodes[14].InnerText;
String ctr_mrc = nodeList[i].ChildNodes[15].InnerText;
}
}
}
}
}
I have created a XML string and Looping that to get value. But its not entering in foreach loop. But in my other code same loop code is working.
my code is :
XML string:
<SuggestedReadings>
<Suggestion Text="Customer Centricity" Link="http://wdp.wharton.upenn.edu/book/customer-centricity/?utm_source=Coursera&utm_medium=Web&utm_campaign=custcent" SuggBy="Pete Fader�s" />
<Suggestion Text="Global Brand Power" Link="http://wdp.wharton.upenn.edu/books/global-brand-power/?utm_source=Coursera&utm_medium=Web&utm_campaign=glbrpower" SuggBy="Barbara Kahn�s" />
</SuggestedReadings>
Code Is:
string str = CD.SRList.Replace("&", "&");
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(str);
XmlNode SuggestionListNode = xmlDoc.SelectSingleNode("/SuggestedReadings/Suggestion");
foreach (XmlNode node in SuggestionListNode)
{
COURSESUGGESTEDREADING CSR = new COURSESUGGESTEDREADING();
var s = db.COURSESUGGESTEDREADINGS.OrderByDescending(o => o.SRID);
CSR.SRID = (s == null ? 0 : s.FirstOrDefault().SRID) + 1;
CSR.COURSEID = LibId;
CSR.TEXT = node.Attributes.GetNamedItem("Text").Value;
CSR.LINK = node.Attributes.GetNamedItem("Link").Value; ;
CSR.SUGBY = node.Attributes.GetNamedItem("SuggBy").Value; ;
CSR.ACTIVEFLAG = "Y";
CSR.CREATEDBY = CD.CreatedBy;
CSR.CREATEDDATE = DateTime.Now;
db.COURSESUGGESTEDREADINGS.Add(CSR);
}
You should use SelectNodes, not SelectSingleNode, since you are trying to get multiple rows out of the XML document.
Use this:
XmlNodeList SuggestionListNode = xmlDoc.SelectNodes("//Suggestion");
foreach (XmlNode node in SuggestionListNode)
{
}
You can try this.
XDocument xdoc = XDocument.Load("data.xml");
var xmlData = from lv1 in xdoc.Descendants("Suggestion")
select new {
Text = lv1.Attribute("Text").Value,
Link = lv1.Attribute("Link").Value,
SuggBy = lv1.Attribute("SuggBy").Value
};
foreach (var item in xmlData){
// your logic here
}
Hi i am reading the RSS feed and creating an XML using the DataTable. This is my code
try
{
DataTable tbl = new DataTable();
tbl.Columns.Add("id");
tbl.Columns.Add("product_name");
tbl.Columns.Add("description");
//Extra Nodes
tbl.Columns.Add("brand");
tbl.Columns.Add("condition");
tbl.Columns.Add("product_type");
XmlDocument doc = new XmlDocument();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(s);
XmlNodeList itemNodes = xmlDoc.SelectNodes("//rss/channel/item");
foreach (XmlNode itemNode in itemNodes)
{
DataRow row = tbl.NewRow();
XmlNode idNode = itemNode.SelectSingleNode("id");
XmlNode product_nameNode = itemNode.SelectSingleNode("product_name");
XmlNode descriptionNode = itemNode.SelectSingleNode("description");
//extra nodes
XmlNode brandNode = itemNode.SelectSingleNode("brand");
XmlNode conditionNode = itemNode.SelectSingleNode("condition");
XmlNode product_typeNode = itemNode.SelectSingleNode("product_type");
if (idNode != null && product_nameNode != null && descriptionNode != null )
{
row[0] = idNode.InnerText;
row[1] = product_nameNode.InnerText;
row[2] = descriptionNode.InnerText;
//extra nodes
if (brandNode == null)
row[3] = "";
else
row[3] = brandNode.InnerText;
if (conditionNode==null)
row[4] = "";
else
row[4] = conditionNode.InnerText;
if (product_typeNode==null)
row[5] = "";
else
row[5] = product_typeNode.InnerText;
}
tbl.Rows.Add(row);
// tbl.Rows.Add(row);
}
}
}
catch (Exception ex)
{
// Console.WriteLine(ex.Message);
// Console.Read();
}
This is working fine without any issue but i want to make my code more efficient. Is this the good way to read the Rss and add into the datatable ? I am making a SSIS project on VS 2008 so i can not use SyndicationFeed .
You can use this code below ans use as example.
using System;
using System.ServiceModel.Syndication;
using System.Xml;
namespace RSSFeed
{
public class Program
{
static void Main(string[] args)
{
// URL from the site you need (RSS Feed in XML please).
String url = "http://www.medicalnewstoday.com/rss/abortion.xml";
// Create XML Reader.
using (XmlReader xmlReader = XmlReader.Create(url, new XmlReaderSettings() { DtdProcessing = DtdProcessing.Ignore }))
{
// Load The Feed.
SyndicationFeed syndicationFeed = SyndicationFeed.Load(xmlReader);
// through the list.
foreach (SyndicationItem item in syndicationFeed.Items)
{
// You can use a lot of information here todo what you need.
// TODO...
// Examples
String subject = item.Title.Text;
String summary = item.Summary.Text;
}
xmlReader.Close();
}
}
}
}
I have an XML file looking like this:
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
<Alert>warning</Alert>
<Alert2>warning</Alert2>
</row>
</data>
When I use the code below I only get the "Alert"-node. But I wan't "Alert2" as well (and so on...). What am I missing here?
using (XmlReader reader = cmd.ExecuteXmlReader())
{
string xmlFile = "";
while (reader.Read())
{
xmlFile = reader.ReadOuterXml();
}
var doc = new XmlDocument();
doc.LoadXml(xmlFile);
var nodes = doc.SelectNodes("data/row");
if (nodes == null) return columns;
var i = 0;
foreach (XmlNode node in nodes)
{
var column = node.ChildNodes[i].Name;
columns.Add(column);
i++;
}
return columns;
}
Change your loop to the equivalent of:
var doc = new XmlDocument();
doc.LoadXml(xml);
var nodes = doc.SelectNodes("data/row");
int i = 0;
foreach (XmlNode node in nodes)
{
foreach (var child in node.ChildNodes)
{
var element = (XmlElement)child;
string nodeName = element.Name;
string value = element.InnerXml;
i++;
}
}