Read xml attribute as object - c#

I have the following simple XML file and I am tying to read the attribute code, using a C# .NET Core Console. I really appetite for any help.
<course type="IT" date="19.09.2019">
<line code="IT001"/>
</course>
UPDATE
I need the result as an object.

Use xml serialization to get a class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(Course));
Course course = (Course)serializer.Deserialize(reader);
}
}
[XmlRoot("course")]
public class Course
{
[XmlAttribute("type")]
public string _type { get; set; }
public DateTime _date { get; set; }
[XmlAttribute("date")]
public string date {
get { return _date.ToString("dd.MM.yyyy"); }
set { _date = DateTime.ParseExact(value, "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture); }
}
private string _code { get; set; }
[XmlElement("line")]
public Line line
{
get { return new Line() { code = _code }; }
set { _code = value.code; }
}
}
[XmlRoot("line")]
public class Line
{
[XmlAttribute("code")]
public string code { get; set; }
}
}

Many ways to skin this cat. Here is a solution by making use of XPath
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<course type=\"IT\" date=\"19.09.2019\"> <line code=\"IT001\"/></course>");
var attrVal = xmlDoc.SelectSingleNode("/course/line/#code").Value;
Console.WriteLine("Attribute 'code' value is " + attrVal);

Related

C# XML Serialization How To Set Attribute xsi:type

This is how my Xml should look after XML Serialization:
<value xsi:type="CD" otherAttributes= "IDK">
.
.
.
</value>
Thats my C# code to it:
public class Valué
{
[XmlAttribute(AttributeName ="xsi:type")]
public string Type { get; set; } = "CD";
[XmlAttribute(attributeName: "otherAttributes")]
public string OtherAttributes { get; set; } = "IDK"
}
Apparently the XmlSerializer can't serialize colons (:) in attributenames.... how do i fix this problem?
If i remove the colon from the attributeName itm works out fine ..
Do it the correct way :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
Valué value = new CD() { OtherAttributes = "IDK" };
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(FILENAME, settings);
XmlSerializer serializer = new XmlSerializer(typeof(Valué));
serializer.Serialize(writer, value);
}
}
[XmlInclude(typeof(CD))]
public class Valué
{
}
public class CD : Valué
{
[XmlAttribute(attributeName: "otherAttributes")]
public string OtherAttributes { get; set; }
}
}

Getting parts of a repetitive string in C#

Extracting parts of a string is a common question, but here the string content, e.g. ' "main\":{\"temp\": ' is repetitive:
string test = "{\"cod\":\"200\",\"message\":0,\"cnt\":40,\"list\":[{\"dt\":1576810800,\"main\":{\"temp\":288.19,\"feels_like\":284.44,\"temp_min\":288.19,\"temp_max\":291.53,\"{\"dt\":1576821600,\"main\":{ \"temp\":283.97,\"feels_like\":281.56,\"temp_min\":283.97,\"temp_max\":286.47,\"pressure\":1007,\"sea_level\":1007,\"grnd_level\":997,\"humidity\":93,\"temp_kf\":-2.5},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rai\",\"icon\":\"10d\"}],\"clouds\":{\"all\":90},\"wind\"";
Using
string s = test.Substring(test.IndexOf("\"main\":{\"temp\":") + 15);
I get
288.19,"feels_like":284.44,,"temp_min":288.19,"temp_max":291.53,"{"dt":157682160
0,"main":{ "temp":283.97,"feels_like":281.56,"temp_min":283.97,"temp_max":286.47
,"pressure":1007,"sea_level":1007,"grnd_level":997,"humidity":93,"temp_kf":-2.5}
,"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}],
"clouds":{"all":90},"wind"
instead of
288.19
Any clue what command would help? Should be something that can be adapted to ' "temp_max" ' or ' "pressure" '.
Cheers
Thanks to Mohammed, here's the working code spitting out all tempeatures:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Newtonsoft.Json;
namespace ConsoleApp2
{
public class RootObject
{
public List<MyList> list { get; set; }
}
public class MyList
{
public Main main { get; set; }
}
public class Main
{
public double temp { get; set; }
}
class Program
{
static void Main()
{
using (WebClient client = new WebClient())
{
Console.WriteLine("ACCESSING ...");
string test = client.DownloadString("http://api.openweathermap.org/data/2.5/forecast?q=Auckland,NZ&APPID=45c3e583468bf450fc17026d6734507e");
//string test = "{\"cod\":\"200\",\"message\":0,\"cnt\":40,\"list\":[{\"dt\":1576810800,\"main\":{\"temp\":288.19,\"feels_like\":284.44,\"temp_min\":288.19,\"temp_max\":291.53,\"{\"dt\":1576821600,\"main\":{ \"temp\":283.97,\"feels_like\":281.56,\"temp_min\":283.97,\"temp_max\":286.47,\"pressure\":1007,\"sea_level\":1007,\"grnd_level\":997,\"humidity\":93,\"temp_kf\":-2.5},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rai\",\"icon\":\"10d\"}],\"clouds\":{\"all\":90},\"wind\"";
var myobject = JsonConvert.DeserializeObject<RootObject>(test); //test is JSON response as string
foreach (var item in myobject.list)
{
var temp = item.main.temp;
Console.WriteLine(temp);
}
Console.ReadLine();
}
}
}
}
Using
var regexGroups = Regex.Matches(test, "\"main\" ?: ?{ ?\"temp\" ?: ?(\\d+\\.\\d+)")
.Select(x => x.Groups[1].Value);
You can get all \"main\":{\"temp\": values.
//classes.cs
public class RootObject
{
public List<MyList> list { get; set; }
}
public class MyList
{
public Main main { get; set; }
}
public class Main
{
public double temp { get; set; }
}
//API client
using Newtonsoft.Json;
var myobject = JsonConvert.DeserializeObject<RootObject>(test); //test is JSON response as string
foreach(var item in myobject.list){
var temp = item.main.temp;
}
//Hope it helps

C# SQLXML Deserialization to Class or Object

http://rtt.metroinfo.org.nz/RTT/Public/Utility/File.aspx?ContentType=SQLXML&Name=JPPlatform.xml
http://rtt.metroinfo.org.nz/RTT/Public/Utility/File.aspx?Name=JPRoutePositionET.xml&ContentType=SQLXML&PlatformTag=536
Both of those are my sample data which I am pulling down using HttpClient, I want to grab the attributes(?) such as PlatformTag, ETA and the like.
This is using Univeral Apps for Windows 10 mobile and Desktop. But I can't figure out what's going on to do it.
XDocument Document = XDocument.Parse(RESPONSE_CONSTANT);
var Stops = from Stop in Document.Descendants("Platform")
select new
{
Platformtag = (string)Stop.Attribute("PlatformTag"),
Platformno = (string)Stop.Attribute("PlatformNo")};
foreach (var item in Stops)
BusData.Text = item.Platformtag;
}
Is what I currently have, but nothing comes from it, it just sits there like it sees nothing, from here I don't know enough about XML Parsing to find a next step.
Note: Response_Constant contains data like this: http://rtt.metroinfo.org.nz/RTT/Public/Utility/File.aspx?Name=JPRoutePositionET.xml&ContentType=SQLXML&PlatformTag=536
Try following. Had to modify xml to replace ampersand.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication14
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
xml = xml.Replace("&", "&");
StringReader sReader = new StringReader(xml);
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
XmlReader reader = XmlReader.Create(sReader);
List<Platform> platforms = new List<Platform>();
while (!reader.EOF)
{
if (reader.Name != "Platform")
{
reader.ReadToFollowing("Platform");
}
if (!reader.EOF)
{
XElement platform = (XElement)XElement.ReadFrom(reader);
platforms.Add(new Platform()
{
tag = (int)platform.Attribute("PlatformTag"),
no = (int?)platform.Attribute("PlatformNo"),
name = (string)platform.Attribute("Name"),
bearingToRoad = (double?)platform.Attribute("BearingToRoad"),
roadName = (string)platform.Attribute("RoadName"),
lat = (double)platform.Element(platform.Name.Namespace + "Position").Attribute("Lat"),
_long = (double)platform.Element(platform.Name.Namespace + "Position").Attribute("Long")
});
}
}
}
}
public class Platform
{
public int tag { get; set; }
public int? no { get; set; }
public string name { get; set; }
public double? bearingToRoad { get; set; }
public string roadName { get; set; }
public double lat { get; set; }
public double _long { get; set; }
}
}

XML deserialization failed to load values to element containing array of elements

I have the following XML file:
<?xml version="1.0" encoding="UTF-8"?>
<TestConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Barcode>MB-B3-00</Barcode>
<TestSuites>
<Test>USB A Slave Port</Test>
<Test>USB B Host Port</Test>
</TestSuites>
</TestConfiguration>
I want to deserialize it into the following class:
public class TestConfiguration
{
private string _barcode;
private string[] _testSuites;
private string[] _testcase;
//Product barcode
public string Barcode
{
get{return this._barcode;}
set{this._barcode = value;}
}
//Test suites
[System.Xml.Serialization.XmlArrayItemAttribute("Test", IsNullable = false)]
public string[] Testsuites
{
get{return this._testSuites;}
set{this._testSuites = value;}
}
//individual test
[System.Xml.Serialization.XmlTextAttribute()]
public string[] Testcase
{
get{return this._testcase;}
set{this._testcase = value;}
}
}
My deserialization code is:
XmlSerializer serializer = new XmlSerializer(typeof(TestConfiguration));
StreamReader reader = new StreamReader(filename);
TestConfiguration _testConfig = (TestConfiguration)serializer.Deserialize(reader);
reader.Close();
However, _testConfig object only contains Barcode value and the properties Testcase and TestSuites are null. Any advice please?
You are very close. The name of your property, Testsuites, doesn't quite match the name of the element <TestSuites> - the capitalization of the letter S differs, and XML Tags are Case Sensitive.
To fix, rename the property or attach an XmlArrayAttribute with the correct element name:
//Test suites
[System.Xml.Serialization.XmlArray("TestSuites")]
[System.Xml.Serialization.XmlArrayItem("Test", IsNullable = false)]
public string[] Testsuites
{
get { return this._testSuites; }
set { this._testSuites = value; }
}
Try this. You can eliminate the tag and have an array of just element. I can show you how.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlSerializer serializer = new XmlSerializer(typeof(TestConfiguration));
StreamReader reader = new StreamReader(FILENAME);
TestConfiguration _testConfig = (TestConfiguration)serializer.Deserialize(reader);
reader.Close();
}
}
[XmlRoot("TestConfiguration")]
public class TestConfiguration
{
private string _barcode;
private string[] _testSuites;
private string[] _testcase;
//Product barcode
[XmlElement("Barcode")]
public string Barcode { get; set; }
//Test suites
[XmlElement("TestSuites")]
public TestSuites testSuites { get; set; }
}
//individual test
[XmlRoot("TestSuites")]
public class TestSuites
{
[XmlElement("Test")]
public List<string> test {get;set;}
}
}
​

Json Deserialization to a class

I have dynamic json result and i want to create an object for that json string. After that i will fill that object with the deserialized object. Here is the json string:
[{"_34":{
"Id":"34",
"Z":["42b23718-bbb8-416e-9241-538ff54c28c9","c25ef97a-89a5-4ed7-89c7-9c6a17c2413b"],
"C":[]
}
}]
How does the object look like? Or how can i deserialize this string to a class.
Thanks.
You can use the JavaScriptSerializer which available out of the box or json.net if you prefer something open source.
Based on Darin Dimitrov's sample, here's how you'd do with json.net:
using System.Collections.Generic;
using System;
using Newtonsoft.Json;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string json = "[{\"_34\":{ \"Id\":\"34\", \"Z\":[\"42b23718-bbb8-416e-9241-538ff54c28c9\",\"c25ef97a-89a5-4ed7-89c7-9c6a17c2413b\"], \"C\":[] } }]";
var result = JsonConvert.DeserializeObject<Dictionary<string, Result>[]>(json);
Console.WriteLine(result[0]["_34"].Z[1]);
}
}
public class Result
{
public string Id { get; set; }
public string[] Z { get; set; }
public string[] C { get; set; }
}
}
Here's an example:
using System;
using System.Collections.Generic;
using System.IO;
using System.Web.Script.Serialization;
public class Result
{
public string Id { get; set; }
public string[] Z { get; set; }
public string[] C { get; set; }
}
class Program
{
static void Main()
{
var json = #"[{""_34"": {""Id"": ""34"",""Z"": [""42b23718-bbb8-416e-9241-538ff54c28c9"",""c25ef97a-89a5-4ed7-89c7-9c6a17c2413b""],""C"": []}}]";
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<Dictionary<string, Result>[]>(json);
Console.WriteLine(result[0]["_34"].Z[1]);
}
}
Target class
public class Target
{
public string Id;
public List<string> Z;
public List<string> C;
}
Deserialization
var ser = new JavaScriptSerializer();
var obj = ser.Deserialize<Target>(json);
Wrap your string in eval function:
var myObject = eval('(' + myJSONtext + ')');

Categories

Resources