Converting XmlDocument as List of objects - c#

At the moment I convert XmlDocument as string List but this is not a good solution becouse if I display it in ListBox this recive me inline string with all parameters and I need to display only of table then when it's checked send it Sql Server
I can't create helper class with properties because parameters can be added/delete dynamically. I don't know what the exact parameters will be in file
Here is example XML
<TechnologyTables>
<Tables>
<TA_ID>3102</TA_ID>
<TA_Name>AL000-01.50M-N2-S0</TA_Name>
<TA_MaterialID>1</TA_MaterialID>
<TA_ThicknessID>4</TA_ThicknessID>
<TA_IsActive>1</TA_IsActive>
<TA_ArchiveID>100</TA_ArchiveID>
<TA_IsArchive>0</TA_IsArchive>
<CL_IsActive>1</CL_IsActive>
<MP_Lens>200</MP_Lens>
<MP_Nozzle>4.0</MP_Nozzle>
<MP_Focal>-0.6</MP_Focal>
<MP_NozzleDist>1.5000000e+000</MP_NozzleDist>
<MP_GasStabilization>1</MP_GasStabilization>
<MP_SensitiveSensor>1</MP_SensitiveSensor>
<MP_SensitiveArea>2.5000000e+001</MP_SensitiveArea>
<GA_ID>1</GA_ID>
<GP_ID>0</GP_ID>
<GP_FlushOn>1</GP_FlushOn>
<GP_FlushTime>2000</GP_FlushTime>
<GP_FlushPressure>1.0000000e+001</GP_FlushPressure>
<GP_FeedbackOn>1</GP_FeedbackOn>
<GP_FeedbackTime>0</GP_FeedbackTime>
<GP_FeedbackPressure>1.0000000e-001</GP_FeedbackPressure>
<GP_MaxPressure>1.0000000e+001</GP_MaxPressure>
<GP_ContinueOn>0</GP_ContinueOn>
<GP_ContinueTime>0</GP_ContinueTime>
<TA_Jerk>100</TA_Jerk>
<TA_Acceleration>100</TA_Acceleration>
<TA_CuttingTechID>3</TA_CuttingTechID>
<TA_FlyCut>1</TA_FlyCut>
<TA_HeadID>1</TA_HeadID>
<TA_MachineID>3</TA_MachineID>
<TA_TypeID>1</TA_TypeID>
<TT_HeadPowerID>7</TT_HeadPowerID>
<TA_CreateDate>2019-08-26T17:10:59.810</TA_CreateDate>
<Description>AL1.5 CATLINE</Description>
<TA_HeadTypeID>2</TA_HeadTypeID>
<CatlineFolder>1</CatlineFolder>
<NozzleNameID>10</NozzleNameID>
<LaserTypeID>1</LaserTypeID>
</Tables>
</TechnologyTables>
Some code when importing file
private async void _ImportTechTables()
{
var open = new OpenFileDialog();
var TableXml = new XmlDocument();
open.Filter = "xml files |*.xml";
if (open.ShowDialog() == DialogResult.OK)
{
TableXml.Load(open.FileName);
}
RSA rsaKey = GetKey();
DecryptXML(TableXml, rsaKey, "XmlKey");
if (TableXml != null)
{
var import = new TechnologyTableImportViewModel();
List<string> xmlNodeLists = new List<string>();
XmlNodeList node = TableXml.SelectNodes("TechnologyTables/Tables");
foreach (XmlNode nodes in node)
{
xmlNodeLists.Add(nodes.InnerXml);
}
import.List = xmlNodeLists;
And element in list look like this:
<Tables><TA_ID><Tables><TA_ID>3102</TA_ID><TA_Name>AL000-01.50M-N2<TA_Name>

I like using a dictionary and create dictionary using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication137
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string, string> dict = doc.Descendants("Tables").FirstOrDefault().Elements()
.GroupBy(x => x.Name.LocalName, y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}
If you have multiple tables then use following :
List<Dictionary<string, string>> dict = doc.Descendants("Tables").Select(t => t.Elements()
.GroupBy(x => x.Name.LocalName, y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault())
).ToList();

You can save the fields to a list this way, although I recommend using a dictionary for this kind of format.
var doc = XDocument.Parse(yourXmlFile);
var table = doc.XPathSelectElement("TechnologyTables/Tables");
var dict = new Dictionary<string, string>();
foreach (var element in table.Elements())
{
dict.Add(element.Name.LocalName, element.Value);
}

Related

resx file to json with specific format in c#

I want to covert resx file in the below json format can you please help me with the same.
{
"TagText.p1":"Inspiration, Motivation",
"TagText.p2":"och utbildning för",
"TagText.p3":"ABO",
"TagText.p4":"globalt...",
"TagText.p5":"Var som helst / När som helst"
}
I have tried the below code.
var xml = File.ReadAllText(#"\Default.aspx.sv-SE.resx");
var obj = new Object();
obj = new
{
Texts = XElement.Parse(xml)
.Elements("data")
.Select(el => new
{
Key = el.Attribute("name").Value,
Value = el.Element("value").Value.Trim(),
})
.ToList()
};
string json = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);
For best results, I think you want to put into a dictionary, and then serialize that. And I'm assuming that your xml has some parent tags wrapping the whole lot of it:
using System;
using System.Xml.Linq;
using System.Linq;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var theXml = #"<myXml><data name=""About.h1"" xml:space=""preserve""> <value>Om</value> <comment>ABOUT</comment> </data> <data name=""AboutUs"" xml:space=""preserve""> <value>Om oss</value> <comment>ABOUT US</comment> </data></myXml>";
var obj = XElement.Parse(theXml)
.Elements("data")
.Select(el => new
{
Key = el.Attribute("name").Value,
Value = el.Element("value").Value.Trim(),
})
.ToDictionary(pair => pair.Key, pair => pair.Value);
string json = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);
Console.Write(json);
}
}
Output:
{
"About.h1": "Om",
"AboutUs": "Om oss"
}
see:
https://dotnetfiddle.net/fQuZZj

C# XML getting the Node & Value of the elements that come under a specific parent

I have an XML as below, I couldn't have multiple data files to be given in app.config and get it moved to the bin/Debug folder during the build. Hence I'm trying to have the test data in one XML file itself.
<?xml version="1.0" encoding="UTF-8"?>
<AppTestData>
<Contact>
<Name>Abe</Name>
<Age>33</Age>
<City>York</City>
...
</Contact>
<Agent>
<Code>A103S</Code>
<Region>North</North>
<Resp>Service</Resp>
....
</Agent>
<Product>
<Cat>Electronics</Cat>
...
</Product>
</AppTestData>
My code will give whether its a Contact / Agent / Product ... and I need the elements below that to be a Dictionary.
XDocument doc = XDocument.Load(new XmlTextReader(xmlName));
Dictionary<string, string> appData = ParseTestDataXML.GetRecordData(<file_path>), "Contact");
foreach (XElement element in doc.Descendants("Contact").Where(p => !p.HasElements))
{
int keyInt = 0;
string keyName = element.Name.LocalName;
while (keyValuePairs.ContainsKey(keyName))
{
keyName = $"{element.Name.LocalName}_{keyInt++}";
}
keyValuePairs.Add(keyName, element.Value);
}
But it adds every other element node and value from other parents like Agent.
I did it, here is the code
Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
XElement root = XElement.Load(filePath);
IEnumerable<XElement> xElements =
from element in root.Elements("Contact") select element;
foreach (XElement el in xElements.Descendants().Where(p => !p.HasElements))
{
int keyInt = 0;
string keyName = el.Name.LocalName;
while (keyValuePairs.ContainsKey(keyName))
{
keyName = $"{el.Name.LocalName}_{keyInt++}";
}
keyValuePairs.Add(keyName, el.Value);
}
Using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
//using a list
Dictionary<string, List<XElement>> appData1 = doc.Root.Elements()
.GroupBy(x => x.Name.LocalName, y => y)
.ToDictionary(x => x.Key, y => y.ToList());
//not using a list
Dictionary<string, XElement> appData2 = doc.Root.Elements()
.GroupBy(x => x.Name.LocalName, y => y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}

How to get the node value by passing type in XDocument C#

I have below XML.
<subscription>
<subscription_add_ons type="array">
<subscription_add_on>
<add_on_code>premium_support</add_on_code>
<name>Premium Support</name>
<quantity type="integer">1</quantity>
<unit_amount_in_cents type="integer">15000</unit_amount_in_cents>
<add_on_type>fixed</add_on_type>
<usage_percentage nil="true"></usage_percentage>
<measured_unit_id nil="true"></measured_unit_id>
</subscription_add_on>
</subscription_add_ons>
My XMLParse function
public XNode GetXmlNodes(XElement xml, string elementName)
{
List<string> addOnCodes= new List<string>();
//elementName = "subscription_add_ons ";
var addOns = xml.DescendantNodes().Where(x => x.Parent.Name == elementName).FirstOrDefault();
foreach (XNode addOn in addOns)
{
//Needed to do something like this
/*var len = "add_on_code".Length + 2;
var sIndex = addOn.ToString().IndexOf("<add_on_code>") + len;
var eIndex = addOn.ToString().IndexOf("</add_on_code>");
var addOnCode = addOn.ToString().Substring(sIndex, (eIndex - sIndex)).Trim().ToLower();
addOnCodes.Add(addOnCode);*/
}
As mentioned in comments by #JonSkeet, I updated my snippet as below.
var addOns = xml.Descendants(elementName).Single().Elements();
foreach (XNode addOn in addOns)
{
/*addon = {<subscription_add_on>
<add_on_code>premium_support</add_on_code>
<name>Premium Support</name>
<quantity type="integer">1</quantity>
<unit_amount_in_cents type="integer">15000</unit_amount_in_cents>
<add_on_type>fixed</add_on_type>
<usage_percentage nil="true"></usage_percentage>
<measured_unit_id nil="true"></measured_unit_id>
</subscription_add_on>} */
//how to get the addOnCode node value ?
var addOnCode = string.Empty;
addOnCodes.Add(addOnCode);
}
But what I need is from the passed XML, get all the nodes of type subscription_add_on then get the value contained in add_on_code & add it to string collection.
Or in general get the value of node by passing type ? Tried with the available methods coming from VS Intellisense but not getting the exact method that can do this?
Thanks!
Here is solution with Xml Linq (XDOCUMENT) :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication107
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("subscription_add_on").Select(x => new
{
add_on_code = (string)x.Element("add_on_code"),
name = (string)x.Element("name"),
quantity = (int)x.Element("quantity"),
amount = (int)x.Element("unit_amount_in_cents"),
add_on_type = (string)x.Element("add_on_type")
}).ToList();
}
}
}

Get the content of a child node from the parent selected by the listbox

i would ask you if it's possible to do the following task:
this is my xml file:
<SETTING_LIST>
<setting>
<name>first</name>
<enable>the command...</enable>
<disable>the command...</disable>
<check>the command...</check>
<word>first</word>
<ifchecktrue>true</ifchecktrue>
<usegrep>true</usegrep>
</setting>
<setting>
<name>second</name>
<enable>the command...</enable>
<disable>the command...</disable>
<check>the command...</check>
<word>first</word>
<ifchecktrue>true</ifchecktrue>
<usegrep>true</usegrep>
</setting>
</SETTING_LIST>
so the user will select from a listbox the name of the parent node like "first" or "second", than i'd need something that give me back the content as string of the child node . I tried something like this but it doesen't work.
private void checkbtn_Click(object sender, EventArgs e)
{
string selectednode = Convert.ToString(listBox1.SelectedItem);
string prompt;
XmlDocument doc = new XmlDocument();
doc.Load("dati.txt");
XmlNode node = doc.SelectSingleNode("setting/" + selectednode + "/check");
prompt = node.InnerText;
MessageBox.Show(prompt);
}
Thank you for your help!!
Use xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq ;
namespace ConsoleApplication1
{
public class Program
{
const string FILENAME = #"c:\temp\test.xml";
public static void Main()
{
XDocument doc = XDocument.Load(FILENAME);
string name = "first";
Dictionary<string, string> dict = doc.Descendants("setting")
.Where(x => (string)x.Element("name") == name).FirstOrDefault()
.Elements().GroupBy(x => x.Name.LocalName, y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}

Store and Access Xml elements using Dictionary in C#

<?xml version="1.0" standalone="yes"?>
<Subject>
<Book>
<Name>ASP.NET</Name>
<Author>ABC</Author>
<Published>2018</Published>
<Price>$100</Price>
</Book>
</Subject>
The above is xml file i have . I want to Store those xml nodes and values in Dictionary and also i need to access the values by using corresponding nodes.
Then only it will works ..
What i have tried is:
XmlTextReader reader = new XmlTextReader("myxmlfile.xml");
Dictionary<string, string> dict = new Dictionary<string, string>();
string field = "";
string strlayer = "";
bool Name = false;
int count = 0;
while (reader.Read())
{
XmlNodeType nt = reader.NodeType;
switch (reader.NodeType)
{
case XmlNodeType.Element:
switch (reader.Name)
{
case "Subject":
count = 1;
break;
case "Book":
count = 1;
break;
case "Name":
if (count == 1)
{
strlayer = reader.Value;
MessageBox.Show(strlayer);
}
else
Name = true;
break;
}
break;
}
}
Am trying the code but its not working.Anyone's help is appreciable ....
i just want to store for that value to that Particular node That's it....
you can use this code:
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load("YOUR_PATH");
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (XmlElement item in xmlDocument.SelectSingleNode("Subject/Book"))
{
dict.Add(item.Name, item.InnerText);
}
if you have only one "Book" element this code help you. but if you have several Book item so you can not use a dictionary to save them.
Using Xml Linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq ;
namespace ConsoleApplication48
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string, string> dict = doc.Descendants("Book").FirstOrDefault().Elements()
.GroupBy(x => x.Name.LocalName, y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}

Categories