How to do Serialization date from XML to C#.NET - c#

<ENVELOPE>
<BODY>
<IMPORTDATA>
<REQUESTDATA>
<TALLYMESSAGE xmlns:UDF="TallyUDF">
<VOUCHER REMOTEID="4b6b9384" VCHKEY="4b6b9384" VCHTYPE="Payment" ACTION="Create" OBJVIEW="Accounting Voucher View">
<DATE>20160102</DATE>
</VOUCHER>
</TALLYMESSAGE>
</REQUESTDATA>
</IMPORTDATA>
</BODY>
</ENVELOPE>
this is the xml file,Now I want to serialize date into .net as like 01/02/2016(dd/mm/yy or mm/dd/yy format)
I tried this two way
objCompanyVouchar.VOUCHER_DATE=XmlConvert.ToDateTime(node.SelectSingleNode("DATE").InnerText)
objCompanyVouchar.VOUCHER_DATE = Convert.ToDateTime(node.SelectSingleNode("DATE").InnerText);
But it show the exception "String was not recognized as a valid DateTime."
Do anyone knows how can I solve this?

Nothing need to do with XmlConvert or required for Convert class.
Let's say you know the format is "yyyyMMdd", then what you need to do is:
var date= DateTime.ParseExact(node.SelectSingleNode("DATE").InnerText,"yyyyMMdd", CultureInfo.InvariantCulture);
objCompanyVouchar.VOUCHER_DATE= date; //If VOUCHER_DATE is DateTime
//objCompanyVouchar.VOUCHER_DATE = date.ToString(); //If VOUCHER_DATE is String
| you can choose the format you want, read more at ToString()

using System;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Serialization;
namespace XMLTest1
{
public class Test
{
public String value1;
public String value2;
}
class listtest
{
static void Main(string[] args)
{
XmlDocument myXml = new XmlDocument();
XPathNavigator xNav = myXml.CreateNavigator();
Test myTest = new Test() { value1 = "Value 1", value2 = "Value 2" };
XmlSerializer x = new XmlSerializer(myTest.GetType());
using (var xs = xNav.AppendChild())
{
x.Serialize(xs, myTest);
}
Console.WriteLine(myXml.OuterXml);
Console.ReadKey();
}
} }

Try 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);
var inportData = doc.Descendants("IMPORTDATA").Select(x => new {
reportName = (string)x.Descendants("REPORTNAME").FirstOrDefault(),
company = (string)x.Descendants("SVCURRENTCOMPANY").FirstOrDefault(),
remoteID = (string)x.Descendants("VOUCHER").FirstOrDefault().Attribute("REMOTEID"),
vchKey = (string)x.Descendants("VOUCHER").FirstOrDefault().Attribute("VCHKEY"),
date = DateTime.ParseExact((string)x.Descendants("DATE").FirstOrDefault(), "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture),
voucherName = (string)x.Descendants("VOUCHERTYPENAME").FirstOrDefault(),
voucherNumber = (int)x.Descendants("VOUCHERNUMBER").FirstOrDefault(),
ledgerName = (string)x.Descendants("PARTYLEDGERNAME").FirstOrDefault()
}).FirstOrDefault();
}
}
}

Related

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

xml, xmlreader read only specific part using c#

I'm using c# to get a parameters from xml file. My problem is I want to read only for the current program parameters. (v1.0, v1.1, v1.2... )
<?xml version="1.0" encoding="utf-8" ?>
<ApplicationPool>
<Resource Version="V1.0">
<Input>2000</Input>
<Input>210</Input>
<Input>65000</Input>
</Resource>
<Resource Version="V1.1">
<Input>2500</Input>
<Input>400</Input>
<Input>130000</Input>
</Resource>
</ApplicationPool>
using (XmlReader reader = XmlReader.Create("testXml.xml"))
{
while (reader.Read())
{
if (reader.IsStartElement())
{
if (reader["Version"] == actualVersion)
{
//??
}
}
}
}
XDocument doc = XDocument.Load("testXml.xml")
var result = doc.Root.Descendants("Resource")
.Where(x => x.Attribute("Version")!= null
&& x.Attribute("Version").Value == actualVersion);
This will return you all Resource nodes in which the Attribute Version == actualVersion. After that you can do whatever you want with the node.
if (reader["Version"] == actualVersion)
{
while (reader.ReadToFollowing("Input"))
{
string value = reader.ReadElementContentAsString();
// or
int value = reader.ReadElementContentAsInt();
}
}
You can use the Xml Linq Approach like:
var xmlFile= XElement.Load(xmlString);
var actualVersion = "V1.1";
var requiredXmlData = xmlFile.Elements("Resource").Where(c=>c.Attribute("Version").Value==actualVersion );
using System.Xml;
...
string actualVersion="V1.1";
XmlDocument rssDoc = new XmlDocument();
rssDoc.Load("testXML.xml");
XmlNodeList _ngroups = rssDoc.GetElementsByTagName("Resource");
for(int i=0;i<=_ngroups.Count-1;i++)
{
if(_ngroups[i].Attributes[0].InnerText.ToString()==actualVersion)
{
for(int j=0;j<=_ngroups[i].ChildNodes.Count-1;j++)
Console.WriteLine(_ngroups[i].ChildNodes[j].InnerText);
}
}
...
Using combination of XmlReader and 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)
{
XmlReader reader = XmlReader.Create(FILENAME);
while (!reader.EOF)
{
if (reader.Name != "Resource")
{
reader.ReadToFollowing("Resource");
}
if (!reader.EOF)
{
XElement resource = (XElement)XElement.ReadFrom(reader);
string version = (string)resource.Attribute("Version");
}
}
}
}
}

Scrub data from xml using c# and xpath

I am trying to delete/Scrub few elements from the xml using c# with the help of xpaths. I am trying to replace the value of social_security_number with "Scrubbed" in both the child tags named "Customers". But my program is landing in many errors. Please correct me.
xml :
<?xml version="1.0" encoding="utf-16"?>
<LoanApplications xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="12345" bundle_id="12225" version="1.0">
<LoanApplication payment_call="False" version="1.0" app_status="I" perform_dupe_check="1" bundle_id="12225" UpdateReviewed="True">
<Customers id = "12" name = "krish" ssn = "123456789">
</LoanApplication>
<LoanApplication deal_type="RESPONSE" payment_call="True" version="1.0" app_status="I" perform_dupe_check="1" bundle_id="12225" UpdateReviewed="True">
<Customers id = "12" name = "krish" ssn = "123456789">
</LoanApplication>
</LoanApplications>
Program :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.Load("mytestfile.xml");
doc.SelectSingleNode("/LoanApplications/LoanApplication[#deal_type="%DealTypeALL%"]/LoanApplicationStates/LoanApplicationState/Customers/Customer[#customer_id="%CustIDALL%"]/").Attributes["social_security_number"].InnerText = "Scrubbed";
doc.Save("mytestfile.xml");
}
}
}
var doc = XDocument.Parse(System.IO.File.ReadAllText("C:\\Users\\jason\\Desktop\\Input\\2015\\09\\03\\mytestfile.xml"));
foreach (var customer in doc.Descendants("Customer"))
{
var ssn = customer.Attribute("social_security_number");
if (ssn != null)
{
ssn.Value = "scrubbed";
}
}
doc.Save("file.xml");
You have few needed nodes instead of one. Thus, you should use SelectNodes instead of SelectSingleNode method.
var doc = new XmlDocument();
doc.Load("mytestfile.xml");
var ssns = doc.SelectNodes("LoanApplications/LoanApplication/LoanApplicationStates/LoanApplicationState/Customers/Customer/#social_security_number");
foreach (XmlAttribute ssn in ssns)
ssn.InnerText = "Scrubbed";
doc.Save("mytestfile.xml");
You can use shorter XPath with descendants. But it has less performance.
var ssns = doc.SelectNodes("//Customer/#social_security_number");
This is real easy with xml linq
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<XElement> ss = doc.Descendants().Where(x => x.Attribute("social_security_number") != null).ToList();
foreach (XElement s in ss)
{
s.Attribute("social_security_number").Value = "Scrubbed";
}
}
}
}

Parsing an XML file and creating a list of its contents

I'm trying to read an XML file and parse its content, but I'm having trouble extracting parameters from the file.
The XML file I'm trying to parse looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<register_map>
<Register ID="1" Index="0x100000" DataType="0x0007" ObjectType="0x07" Name="Device Type"/>
<Register ID="2" Index="0x100100" DataType="0x0005" ObjectType="0x07" Name="Error Register"/>
</register_map>
</root>
My code so far looks like this
namespace Test_XML
{
class Program
{
struct RegisterEntry
{
public UInt32 index;
public UInt16 dataType;
public UInt16 objectType;
public string name;
};
static void Main(string[] args)
{
XDocument doc = XDocument.Load("registers.xml");
var registers = doc.Descendants("register_map");
foreach (var register in registers)
{
// Fill up a list of RegisterEntrys with contents of XML
}
Console.ReadLine();
}
}
}
How can I extract the parameters from "registers" and place them in a RegisterEntry object?
You can use
var registers = doc.XPathSelectElements("/root/register_map/Register");
It will give you collection of Registernodes, so you wil be able to access their attributes and populate your RegisterEntry object something like:
foreach (var register in registers)
{
var dataType = register.Attribute("DataType").Value;
//the rest of the code
}
Notice XPathSelectElements is an extension method in System.Xml.XPath namespace. Make sure you've referenced System.Xml.Linq assembly in order to use it.
You should use .Attributes["name"].Value. I take it you want those values converted to Int as well, so we need an additional Convert.ToInt(string, base);
var RegisteryEntryList = new List<RegistryEntry>();
foreach (var register in registers)
{
//create a new RegistryEntry
var obj = new RegistryEntry();
//convert your string to an int value and save it
obj.index = Convert.ToInt32(register.Attributes["Index"].Value.Split('x')[1], 8);
obj.datatype = Convert.ToInt32(register.Attributes["DataType"].Value.Split('x')[1], 8);
//... your remaining properties
RegisteryEntryList.Add(obj);
}
Please note: If your Index is binary (base 2) you need to adapt the conversion accordingly. For more information see https://msdn.microsoft.com/en-us/library/1k20k614(v=vs.110).aspx
Your query will get you all elements with the name register_map - you want all Register elements. Change it to this:
var registers = doc.Descendants("Registers");
Then iterate through them and take the values you need, converting them to the required types.
foreach (var register in registers)
{
var indexHex = (string)register.Attribute("Index");
var index = Convert.ToUInt32(indexHex, 16);
var dataTypeHex = (string)register.Attribute("DataType");
var dataType = Convert.ToUInt16(dataTypeHex, 16);
var objectTypeHex = (string)register.Attribute("ObjectType");
var objectType = Convert.ToUInt16(objectTypeHex, 16);
var name = (string)register.Attribute("Name");
var entry = new RegisterEntry
{
index = index,
dataType = dataType,
objectType = objectType,
name = name,
};
// do something with entry
}
Use xml Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<root>" +
"<register_map>" +
"<Register ID=\"1\" Index=\"0x100000\" DataType=\"0x0007\" ObjectType=\"0x07\" Name=\"Device Type\"/>" +
"<Register ID=\"2\" Index=\"0x100100\" DataType=\"0x0005\" ObjectType=\"0x07\" Name=\"Error Register\"/>" +
"</register_map>" +
"</root>";
XDocument doc = XDocument.Parse(xml);
var results = doc.Descendants("Register").Select(x => new {
id = (int)x.Attribute("ID"),
index = int.Parse(x.Attribute("Index").Value.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture),
dataType = int.Parse(x.Attribute("DataType").Value.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture),
objectType = int.Parse(x.Attribute("ObjectType").Value.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture),
name = (string)x.Attribute("Name")
}).ToList();
}
}
}

How to set value in nested LINQ select to parent select result?

This is my LINQ:
var sdEnumTypes = from et in sdXmlEnums.Elements("Enum")
select new SdEnum
{
Name = et.Attribute("name").Value,
EnumGuid = et.Attribute("guid").Value,
Enumerators = (from en in et.Elements("Enumerator")
select new SdEnumerator
{
DisplayName = en.Attribute("displayName").Value,
Name = en.Attribute("name").Value
//Enum = I want this to point to parent SdEnum
}).ToList()
};
I want to set (commented part) Enum value to SdEnum that is being selected on level up. How to do it?
This is corresponding XML that is being parsed for you to visualize what I want to do:
<Enums>
<Enum name="Color" guid="{2C68F947-3103-4F3C-9855-60F289B3A039}">
<Enumerator name="Red" displayName="Red Color"/>
<Enumerator name="Green" displayName="Green Color" />
<Enumerator name="Blue" displayName="BlueColor"/>
</Enum>
</Enums>
P.S.
Is there any way to simplify this this query?
Here is a method 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
{
static void Main(string[] args)
{
string input =
"<Enums>" +
"<Enum name=\"Color\" guid=\"{2C68F947-3103-4F3C-9855-60F289B3A039}\">" +
"<Enumerator name=\"Red\" displayName=\"Red Color\"/>" +
"<Enumerator name=\"Green\" displayName=\"Green Color\" />" +
"<Enumerator name=\"Blue\" displayName=\"BlueColor\"/>" +
"</Enum>" +
"</Enums>";
XDocument doc = XDocument.Parse(input);
var results = doc.Descendants("Enum").Select(x => new {
name = x.Attribute("name").Value,
guid = x.Attribute("guid").Value,
enumerator = x.Elements("Enumerator").Select(y => new {
name = y.Attribute("name").Value,
displayName = y.Attribute("displayName").Value,
parent = x
}).ToList()
}).ToList();
}
}
}
​
The simplest way to do this is to use another projection:
var result = sdEnumTypes.Select(e =>
{
e.Enumerators.ForEach(enumerator => enumerator.Enum = e);
return e;
});

Categories