I use Nhibernate and sometimes I get error like "String or binary data would be truncated in table..." because of sql restrictions. Is there a way to limit string length?
I limit properties individualy like here.
public void myMethod()
{
myClass myClass1= new MyClass()
{
id = 1,
prop1 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat"
}
saveMethod(myClass1);
}
public void saveMethod(myClass entity)
{
entity.prop1=entity.prop1?.Substring(0,Math.Min(100,entity.prop1.Length));
_repository.insert(entity);
}
public class myClass
{
public virtual int id { get; set; }
public virtual string prop1 { get; set; }
}
I use MSSQL for database.
public virtual string Prop1 { get => _prop1; set { _prop1 = value?.Substring(0, MaxLength); OnPropertyChanged(); } }
or with https://nhibernate.info/doc/validator/nhibernate-validator-1-0-0-documentation
[Length(Max=MaxLength)]
public virtual string prop1 { get; set; }
Related
I am working on a word recognition in automata, and for the exchange of information I need to create an XML file of my object.
already use the library using System.Xml.Serialization;
[Serializable]
class Automata
{
public List<int> estado_Q { get; set; }
public List<char> alfabeto_X { get; set; }
public List<Transicion> ftrans_t { get; set; }
public int estadoInicio_qo { get; set; }
public List<int> estadosFinales_F { get; set; }
public Automata(List<int> Q, List<char> X, List<Transicion> T, int qo, List<int> F)
{
estado_Q = Q;
alfabeto_X = X;
ftrans_t = T;
estadoInicio_qo = qo;
estadosFinales_F = F;
}
}`
[Serializable]
class Transicion
{
public int fromEstado { get; set; }
public char leeyendo { get; set; }
public int untilEstado { get; set; }
public Transicion(int iEstado, char leer, int fEstado)
{
fromEstado = iEstado;
leeyendo = leer;
untilEstado = fEstado;
}
}
static void Main(string[] args)
{
Clases.Automata au = new Clases.Automata();
var automatalista = new Automata();
XmlSerializer serializer = new XmlSerializer(typeof(List<Automata>));
using (TextWriter writer = new StreamWriter("C:\\Users\\user\\Downloads\\Temp\\File.xml"))
{
serializer.Serialize(writer, automatalista);
}
}
I want you to generate an XML file, but I get an error.`
System.InvalidOperationException: 'Create Xml Object.Program no es accesible por el nivel de protección. Sólo se pueden procesar tipos públicos.'
You need to make the types public. EG
public class Automata . . .
I am writing unit tests for my generic repository, but when I run my update method it fails.
My test method looks like this:
private async Task TestUpdate()
{
var compare = testArticles[0];
var article = await testInstance.SelectSingleAsync(new AdHocSpecification<Article>(x => x.Id == compare.Id), x => x.ArticleImages).ConfigureAwait(false);
Compare(article, compare);
article.Brand = "Air-Bam";
article.DescriptionDutch = "Ter aldus dus juist wij zware. Hadden met karank afzien dat oog dus invoer oorlog. Oogenblik zoo volledige zin mag stoompomp schatkist. Per had met tot sinds batoe zelfs. Dit opgericht producten ontrukten schatkist het. Verkoopen ons die omgewoeld gebergten honderden dus het.";
article.DescriptionFrench = "Comme verts mes comme ces nul fut. Et ah te avons rente rouge je. Il ainsi il cause oh croix utile or. Jeunesse poitrine en epanouir la reparler la. Jet noble force par arret ras voila votre peu. Les ete appareil supplice vit epandent. Collines dissiper cavalier octogone la magasins ca.";
article.Discount = 80;
article.IsDeleted = true;
article.Price = 1000;
article.Title = "Air Tone";
await testInstance.UpdateAsync(article).ConfigureAwait(false);
Assert.AreNotEqual(article.Brand, compare.Brand);
Assert.IsNotNull(article.ArticleImages);
Assert.IsFalse(article.ArticleImages.ToList().SequenceEqual(compare.ArticleImages.ToList()));
Assert.AreNotEqual(article.DescriptionDutch, compare.DescriptionDutch);
Assert.AreNotEqual(article.DescriptionFrench, compare.DescriptionFrench);
Assert.AreNotEqual(article.Discount, compare.Discount);
Assert.AreNotEqual(article.IsDeleted, compare.IsDeleted);
Assert.AreNotEqual(article.Price, compare.Price);
Assert.AreNotEqual(article.Title, compare.Title);
}
The SelectSingleAsync and UpdateAsync methods look like the following:
public virtual Task<TObj> SelectSingleAsync(Specification<TObj> spec, params Expression<Func<TObj, object>>[] includes)
{
return _context.Set<TObj>().Includes(includes).Where(spec.ToExpression()).AsNoTracking().FirstOrDefaultAsync();
}
public virtual async Task UpdateAsync(TObj obj)
{
_context.Set<TObj>().Update(obj);
await _context.SaveChangesAsync().ConfigureAwait(false);
}
When the Update method gets executed, an exception gets thrown:
System.InvalidOperationException: The instance of entity type 'Article' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
I do not understand why it is saying that it is already being tracked, as I am clearly using AsNoTracking() in my select method. What can I do to fix this?
Edit: The Article class looks like the following
public class Article:Entity<Guid>
{
public string Title { get; set; }
public string Brand { get; set; }
public string DescriptionDutch { get; set; }
public string DescriptionFrench { get; set; }
public decimal Price { get; set; }
public int Discount { get; set; }
public ICollection<ArticleImage> ArticleImages { get; set; }
public override bool Equals(object obj)
{
if (!(obj is Article article)) return false;
return article.Title.Equals(Title)
&& article.Id.Equals(Id)
&& article.IsDeleted.Equals(IsDeleted)
&& article.Brand.Equals(Brand)
&& article.DescriptionDutch.Equals(DescriptionDutch)
&& article.DescriptionFrench.Equals(DescriptionFrench)
&& article.Price.Equals(Price)
&& article.Discount.Equals(Discount)
&& article.ArticleImages.SequenceEqual(ArticleImages);
}
}
public abstract class Entity<TKey> where TKey : struct
{
[Key] public TKey Id { get; set; }
public bool IsDeleted { get; set; }
}
My context class looks like this:
public class ApplicationDbContext : IdentityDbContext<User>, IApplicationDbContext
{
public ApplicationDbContext(DbContextOptions options)
: base(options)
{
}
public ApplicationDbContext()
{
}
public DbSet<HomePageItem> HomePageItem { get; set; }
public DbSet<Country> Country { get; set; }
public DbSet<Address> Address { get; set; }
public DbSet<Translation> Translation { get; set; }
public DbSet<Article> Article { get; set; }
public DbSet<ArticleImage> ArticleImage { get; set; }
}
Edit 2: Example of article that gets inserted:
new Article
{
Brand = "Lorem",
ArticleImages = new List<ArticleImage>{
new ArticleImage
{
Order = 0,
Url = "foo"
},
new ArticleImage
{
Order = 1,
Url = "bar"
}
},
DescriptionDutch = "Wier heft zien mont gaat zijn al en of. Wel brusch zin worden dienen bladen des vooral oosten. Nam behoeft noemden haalden elk. Stuit spijt enkel vogel oog een vindt geldt. Aangewend bezetting wijselijk arbeiders om is op antwerpen japansche af. Systemen planters vreemden kan hen passeert ons dichtbij dit. Met gevestigd wij financien als behoeften.",
DescriptionFrench = "Air courtes reciter moi affreux croisee. La xv large en etais roidi ponts terre. Siens homme pic peu jeu glace beaux. Ca ma apres pitie sacre monde et voici. Battirent il echangent la croissent esplanade sortaient du ce. Fanatiques infanterie eux mon etonnement ecouterent imprudente assurances. Bambous fleurir ai arriere tu longues souffle etoffes un.",
Discount = 10,
IsDeleted = false,
Price = 200,
Title = "Tipfan"
}
Code that does the insert:
public virtual async Task InsertAsync(TObj obj)
{
_context.Set<TObj>().Add(obj);
await _context.SaveChangesAsync().ConfigureAwait(false);
}
Try to repair your code like this:
public class Article:Entity<Guid>
{
public string Title { get; set; }
public string Brand { get; set; }
public string DescriptionDutch { get; set; }
public string DescriptionFrench { get; set; }
public decimal Price { get; set; }
public int Discount { get; set; }
public ICollection<ArticleImage> ArticleImages { get; set; }
//add constructor, and initilize the id
public Article(){
this.Id = Guid.NewGuid();
}
public override bool Equals(object obj)
{
if (!(obj is Article article)) return false;
return article.Title.Equals(Title)
&& article.Id.Equals(Id)
&& article.IsDeleted.Equals(IsDeleted)
&& article.Brand.Equals(Brand)
&& article.DescriptionDutch.Equals(DescriptionDutch)
&& article.DescriptionFrench.Equals(DescriptionFrench)
&& article.Price.Equals(Price)
&& article.Discount.Equals(Discount)
&& article.ArticleImages.SequenceEqual(ArticleImages);
}
}
When you fetch data from database, and iterate over it, like:
var dataObject = await dbContext.Table.where(x=>x.UserId == model.UserId).TolistAsync();
foreach(var item in dataObject)
{
}
do not create another object, pass the fetched object directly to Delete or use it to update, because DbContext is tracking the objects it has fetched, not the ones you create. for example:
//Wrong code
var dataObject = await dbContext.Table.where(x=>x.UserId == model.UserId).TolistAsync();
foreach(var item in dataObject)
{
var x=new DataObject()
{
x=item.Id
};
dbContext.Table.Remove(x);
}
you must pass the originally fetched instance to Remove() method, see:
var dataObject = await dbContext.Table.where(x=>x.UserId == model.UserId).TolistAsync();
foreach(var item in dataObject)
{
dbContext.Table.Remove(item);
}
namespace FBLALibraryApp2
{
public partial class GenrePage : ContentPage
{
public GenrePage()
{
InitializeComponent();
listView.ItemsSource = DataStorage.GenreList;
}
private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
{
}
private void listView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
listView.SelectedItem = null;
}
async private void listView_ItemTapped(object sender, ItemTappedEventArgs e)
{
if (e.Item is GenreGroup)
await Navigation.PushAsync(new GenreView((GenreGroup)e.Item));
}
}
}
Here is the code for a page that I have made in Xamarin. It is a simple page that displays a list of GenreGroup's. It has worked fine in the past, but recently, when I changed my code initializing the list, the application would run to a blank screen. So, I paused debugging and saw it was stuck at, initially, listView.ItemSource = DataStorage.GenreList;. Upon hitting continue, the application would throw a TypeInitializationException. I was worried that perhaps the most recent version of my code was not being built (this has happened to me before with Fast Deployment enabled), so I added a Debug.log("x"); before the troublesome line to ensure that the most recent code was being run. Upon doing this, the application began freezing on InitializeComponent() and throwing the same exception. I am stumped here as to what to do. Here is the code for where I declare the list:
public static class DataStorage
{
public static List<Book> AllBookList = new List<Book> { new Book { Title = "Harry Potter", Author = "J.K. Rowling", Summary="lorem ipsum dolorum sdjfa;dklfja;dkfj;akdfja;dfjkaf", Genre= new string[] { "Fantasy", "Adventure" }, pubYear="2017" }, new Book { Title = "The Hunger Games", Author = "Suzanne Collins", Summary = "lorem ipsum dolorum sdjfa;dklfja;dkfj;akdfja;dfjkaf", Genre = new string[] { "Sci-Fi" }, pubYear = "2017" }, new Book { Title = "Thief in the Night", Author = "Jack Nimble", Summary = "lorem ipsum dolorum sdjfa;dklfja;dkfj;akdfja;dfjkaf", Genre = new string[] { "Mystery"}, pubYear = "2017" }, new Book { Title = "Hardy Bros.", Author = "Johnny Heather", Summary = "lorem ipsum dolorum sdjfa;dklfja;dkfj;akdfja;dfjkaf", Genre = new string[] { "Mystery", "Comedy" }, pubYear = "2017" } };
public static List<GenreGroup> GenreList = new List<GenreGroup> { new GenreGroup("Mystery", "jd;akfjd;"), new GenreGroup("Fantasy", "dja;fdjkl") };
public static GenreGroup Mystery = new GenreGroup("Mystery","djfsldfjldjF");
public static GenreGroup Fantasy = new GenreGroup("Fantasy", "djfsldfjldjF");
static DataStorage()
{
foreach (Book book in AllBookList)
{
for (int x = 0; x < book.Genre.Length; x++)
{
if (book.Genre[x] == "Mystery")
{
Mystery.Add(book);
}
else if (book.Genre[x] == "Fantasy")
{
Fantasy.Add(book);
}
}
}
GenreList = new List<GenreGroup> { Mystery, Fantasy };
}
}
I suspect the issue is somewhere in this code, as this is what I changed. Note: I understand that my code right now is a little strange and I define GenreList explicitly, and then redefine it later, but I was trying to ensure it wasn't null for whatever reason. Thanks for any help
Update: upon placing Debug.WriteLine BEFORE InitializeComponent, it now freezes on Debug.WriteLIne and throws the same, TypeInitializationEXception
Update: Here is the code for GenreGroup and Book
public class GenreGroup : List<Book>
{
public string Title { get; set; }
public string Description { get; set; }
public GenreGroup(string title, string description)
{
Title = title;
Description = description;
}
}
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
public string Summary { get; set; }
public string[] subjectHeadings { get; set; }
public string[] Genre { get; set; }
public string pubYear { get; set; }
}
You' re missing initializations here:
public static GenreGroup Mystery; // Init this
public static GenreGroup Fantasy; // And this
Edit: I just ran your code and it's fine. Just clean your project and rebuild it. VS has plenty of bugs. Cheers.
listView.ItemsSource = DataStorage.GenreList;
This line will call static DataStorage(), in this static constructor, Mystery and Fantasy should be initialized before you call it. So the solution should be this:
1) Add public GenreGroup() { } in your GenreGroup class;
2) Init Mystery and Fantasy in DataStorage class:
public static GenreGroup Mystery = new GenreGroup();
public static GenreGroup Fantasy = new GenreGroup();
How can I query (to see if a property exists) and enumerate (the array property) found within a complex JSON object using using JSON.NET in C# ?
I am receiving a complex JSON object from an API with a variable number/type of properties.
I keep reading the JSON.Net Documentation, reviewing samples, etc. but not gotten far and am lost in JObject, JArray, JToken, using dynamic, etc...
I want to find the pageResponses.scriptOutput property, verify it contains and .items[] array and then enumerate/iterate the array.
Edit
I made progress and found typo in JSON data example.
But how can I query/enumerate the child objects using key names, e.g.(item.location, item.timestamp) ?
string json = File.ReadAllText(#"Output.json");
JObject jObj = JObject.Parse(json);
IList<JToken> items = jObj["pageResponses"][0]["scriptOutput"]["items"].ToList();
foreach (JToken item in items){
Console.WriteLine(item["location"]);
}
/*** Console Output ***/
// Austin, TX
// Anaheim, CA
// Adams, MN
// Barstow, CA
var varItems = from o in jObj["pageResponses"][0]["scriptOutput"]["items"].ToList() select o;
foreach (var item in varItems){
Console.WriteLine(item["timestamp"]);
}
/*** Console Output ***/
// 2016 - 05 - 03 19:53
// 2016 - 05 - 04 04:10
// 2016 - 05 - 04 08:18
// 2016 - 05 - 01 12:26
(JSON sample below trimmed down for brevity)
{
"meta": {
"outputAsJson": true,
"backend": {
"os": "linux",
"id": "10.240.0.3_2",
"requestsProcessed": 8
}
},
"pageResponses": [
{
"pageRequest": {
"renderType": "script",
"outputAsJson": true
},
"frameData": {
"name": "",
"childCount": 1
},
"events": [
{
"key": "navigationRequested",
"time": "2016-05-06T13:43:30.344Z"
},
{
"key": "navigationRequested",
"time": "2016-05-06T13:43:31.131Z"
}
],
"scriptOutput": {
"items": [
{
"location": "Austin, TX",
"timestamp": "2016-05-03 19:53",
"title": "User Login"
},
{
"location": "Anaheim, CA",
"timestamp": "2016-05-04 04:10",
"title": "User Logout"
},
{
"location": "Adams, MN",
"timestamp": "2016-05-04 08:18",
"title": "User Login"
},
{
"location": "Barstow, CA",
"timestamp": "2016-05-01 12:26",
"title": "User Logout"
}
]
},
"statusCode": 200
}
],
"statusCode": 200,
"content": {
"name": "content.json",
"encoding": "utf8"
},
"originalRequest": {
"pages": [
{
"renderType": "script",
"outputAsJson": true
}
]
}
}
I suggest creating a proxy class (I used json2csharp):
public class Backend
{
public string os { get; set; }
public string id { get; set; }
public int requestsProcessed { get; set; }
}
public class Meta
{
public bool outputAsJson { get; set; }
public Backend backend { get; set; }
}
public class PageRequest
{
public string renderType { get; set; }
public bool outputAsJson { get; set; }
}
public class FrameData
{
public string name { get; set; }
public int childCount { get; set; }
}
public class Event
{
public string key { get; set; }
public string time { get; set; }
}
public class ScriptOutput
{
public List<object> items { get; set; }
}
public class PageRespons
{
public PageRequest pageRequest { get; set; }
public FrameData frameData { get; set; }
public List<Event> events { get; set; }
public ScriptOutput scriptOutput { get; set; }
public int statusCode { get; set; }
}
public class Content
{
public string name { get; set; }
public string encoding { get; set; }
}
public class Page
{
public string renderType { get; set; }
public bool outputAsJson { get; set; }
}
public class OriginalRequest
{
public List<Page> pages { get; set; }
}
public class RootObject
{
public Meta meta { get; set; }
public List<PageRespons> pageResponses { get; set; }
public int statusCode { get; set; }
public Content content { get; set; }
public OriginalRequest originalRequest { get; set; }
}
Then deserialize it:
var obj = JsonConvert.DeserializeObject<RootObject>(json);
if (obj != null && obj.pageResponses != null)
{
foreach (var pageResponse in obj.pageResponses)
{
if (pageResponse.scriptOutput == null)
continue;
foreach (var item in pageResponse.scriptOutput.items)
{
Console.WriteLine(item);
}
}
}
I do this with a couple of Extension Methods and I use JsonConvert.DeserializeObject.
Code snippets below.
Usage
ExpandoObject data = JsonConvert.DeserializeObject<ExpandoObject>(jsonString);
if(data.HasProperty("propertyToCheck"))
{
object[] objects = data.Get<object[]>("propertyToCheck");
}
In the snippet above I check a property exists, then I assign it to a .Net type, in this case an object array. Though it can be any type so long as it's sane.
Extension Methods
public static bool HasProperty(this ExpandoObject value, string property)
{
bool hasProp = false;
if (((IDictionary<String, object>)value).ContainsKey(property))
{
hasProp = true;
}
return hasProp;
}
public static T Get<T>(this ExpandoObject value, string property)
{
return (T)((IDictionary<String, dynamic>)value)[property];
}
Quick, easy and to the point!
I have the following code of my class,
public class ClassGPS
{
[XmlElement("head")]
public Head head;
[XmlElement("events")]
public Events events;
public class Head
{
[XmlAttribute("nemo")]
public string Nemo { get; set; }
[XmlAttribute("dte")]
public string Dte { get; set; }
}
public class Events
{
[XmlElement("event")]
public _EVENT events;
}
public class _EVENT
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlAttribute("desc")]
public string Desc { get; set; }
[XmlElement("gps")]
public _GPS gps;
[XmlElement("mov")]
public _MOV mov;
[XmlElement("geo")]
public _GEO geo;
[XmlElement("passengers")]
public _PASSENGERS passengers;
[XmlElement("sensors")]
public _SENSORS sensors;
}
public class _GPS
{
[XmlAttribute("id")]
public string Id { get; set; }
[XmlAttribute("dte")]
public string Dte { get; set; }
}
public class _MOV
{
[XmlAttribute("plate")]
public string Plate { get; set; }
[XmlAttribute("vel")]
public string Vel { get; set; }
[XmlAttribute("odo")]
public string Odo { get; set; }
[XmlAttribute("rpm")]
public string Rpm { get; set; }
[XmlAttribute("rutDri")]
public string Rutdri { get; set; }
[XmlAttribute("tipDri")]
public string Tipdri { get; set; }
}
public class _GEO
{
[XmlAttribute("lat")]
public string Lat { get; set; }
[XmlAttribute("long")]
public string Long { get; set; }
[XmlAttribute("alt")]
public string Alt { get; set; }
[XmlAttribute("dir")]
public string Dir { get; set; }
}
public class _PASSENGERS
{
[XmlElement("pass")]
public _PASS pass;
}
public class _PASS
{
[XmlAttribute("id")]
public string Id { get; set; }
[XmlAttribute("rut")]
public string Rut { get; set; }
[XmlAttribute("tip")]
public string Tip { get; set; }
}
public class _SENSORS
{
[XmlElement("sensor")]
public _SENSOR sensor;
}
public class _SENSOR
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlAttribute("id")]
public string Id { get; set; }
[XmlAttribute("unit")]
public string Unit { get; set; }
[XmlAttribute("value")]
public string Value { get; set; }
}
}
and use the code below to fill
public ClassGPS esb()
{
List<ClassGPS._EVENT> listevent = new List<ClassGPS._EVENT>();
List<ClassGPS._PASSENGERS> listpassegers = new List<ClassGPS._PASSENGERS>();
List<ClassGPS._SENSORS> listsensors = new List<ClassGPS._SENSORS>();
ClassGPS gps = new ClassGPS
{
head = new ClassGPS.Head { Nemo = "XYS-XML", Dte = "2012-02-02 15:05:05.456" },
events = new ClassGPS.Events
{
for (int i = 1; i <= 5 ; i++) {
listevent.Add (new ClassGPS._EVENT
{
Type = "PPT",
Desc = "position_time",
gps = new ClassGPS._GPS { Id = i, Dte = "2012-02-02 15:05:05.456" },
mov = new ClassGPS._MOV { Plate = "111456-2", Vel = "98", Odo = "45678987", Rpm = "465489", Rutdri = "13649654", Tipdri = "23133216" },
geo = new ClassGPS._GEO { Lat = "-34.324", Long = "70.366", Alt = "32.506", Dir = "86.32123" },
passengers = new ClassGPS._PASSENGERS
{
for (int x = 1; x <= 9 ; x++) {
listpassegers.Add ( new ClassGPS._PASS {
Id = x,
Rut = "2132132",
Tip = "121325646" })
}
},
sensors = new ClassGPS._SENSORS
{
for (int y = 1; x <= 3 ; x++) {
listsensors.Add ( new ClassGPS._SENSOR {
Type ="LS",
Id = y,
Unit= "%" ,
Value="21" })
}
}
})
}
}
};
return gps;
}
I cannot fill with the code because I don't know how.
I need the following result.
<ClassGPS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<head nemo="XYS-XML" dte="2012-02-02 15:05:05.456" />
<events>
<event type="PPT" desc="position_time">
<gps id="213212315646" dte="2012-02-02 15:05:05.456" />
<mov plate="111456-2" vel="98" odo="45678987" rpm="465489" rutDri="13649654" tipDri="23133216" />
<geo lat="-34.324" long="70.366" alt="32.506" dir="86.32123" />
<passengers>
<pass id="1" rut="2132132" tip="121325646" />
</passengers>
<sensors>
<sensor type="LS" id="1" unit="%" value="21" />
<sensor type="LS" id="1" unit="%" value="21" />
</sensors>
</event>
<event type="PPT" desc="position_time">
<gps id="213212315646" dte="2012-02-02 15:05:05.456" />
<mov plate="111456-2" vel="98" odo="45678987" rpm="465489" rutDri="13649654" tipDri="23133216" />
<geo lat="-34.324" long="70.366" alt="32.506" dir="86.32123" />
<passengers>
<pass id="1" rut="2132132" tip="121325646" />
<pass id="2" rut="2132546132" tip="1213256546" />
</passengers>
<sensors>
<sensor type="LS" id="1" unit="%" value="21" />
</sensors>
</event>
</events>
The passengers, sensors and events can be more than one.
I've modified and shortened your code slightly.
public class Gps
{
[XmlElement("head")]
public HeadData Head { get; set; }
[XmlArray("events")]
[XmlArrayItem("event")]
public List<EventData> Events { get; set; }
public class HeadData
{
[XmlAttribute("nemo")]
public string Nemo { get; set; }
[XmlAttribute("dte")]
public DateTime Dte { get; set; }
}
public class EventData
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlAttribute("desc")]
public string Desc { get; set; }
[XmlElement("gps")]
public GpsData Gps { get; set; }
}
public class GpsData
{
[XmlAttribute("id")]
public string Id { get; set; }
[XmlAttribute("dte")]
public DateTime Dte { get; set; }
}
}
Populate data and serialize
private static void Main(string[] args)
{
var eventData = new List<Gps.EventData>();
for (int i = 0; i < 5; ++i)
{
eventData.Add(new Gps.EventData
{
Desc = "X",
Type = "Y",
Gps = new Gps.GpsData
{
Dte = DateTime.Now,
Id = i.ToString()
}
});
}
Gps gps = new Gps()
{
Head = new Gps.HeadData {Dte = DateTime.Now, Nemo = "XYS-XML"},
Events = eventData
};
var serializer = new XmlSerializer(gps.GetType());
using (var writer = new StreamWriter(#"C:\temp\gps.xml"))
{
serializer.Serialize(writer, gps);
}
Console.ReadLine();
}
XML result
<?xml version="1.0" encoding="utf-8"?>
<Gps xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<head nemo="XYS-XML" dte="2015-04-27T18:48:47.9499022+02:00" />
<events>
<event type="Y" desc="X">
<gps id="0" dte="2015-04-27T18:48:47.9489022+02:00" />
</event>
<event type="Y" desc="X">
<gps id="1" dte="2015-04-27T18:48:47.9499022+02:00" />
</event>
<event type="Y" desc="X">
<gps id="2" dte="2015-04-27T18:48:47.9499022+02:00" />
</event>
<event type="Y" desc="X">
<gps id="3" dte="2015-04-27T18:48:47.9499022+02:00" />
</event>
<event type="Y" desc="X">
<gps id="4" dte="2015-04-27T18:48:47.9499022+02:00" />
</event>
</events>
</Gps>