I need to be able to define two nodes with the same name but completely different subnode structures. I didn't design this XML schema but for the time being I'm forced to use it as is. I realize it's a terrible abuse of everything that is XML but there you have it.
What I need it to look like:
<order>
<ItemType type="Clubs">
<Club num="1">
<ClubName>Some Name</ClubName>
<ClubChoice>Something Else</ClubChoice>
</Club>
</ItemType>
<ItemType type="Gift" val="MailGreeting">
<GiftName>MailGreeting</GiftName>
<GiftDescription></GiftDescription>
<GiftQuanity>1</GiftQuanity>
</ItemType
</order>
Of course it's far more complicated than but you get the gist.
I'm using XmlSerializer and would really like to avoid using XDocument but if that's what I need to do then so be it.
If your order contains properties and not a list you can tell the serializer to name the elements like this:
[XmlRoot("order")]
public class Order
{
private Whatever whateverInstance;
[XmlElement("ItemType")]
public Whatever WhateverInstance
{
get { return whateverInstance; }
set { whateverInstance = value; }
}
private Something somethingInstance;
[XmlElement("ItemType")]
public Something SomethingInstance
{
get { return somethingInstance; }
set { somethingInstance = value; }
}
}
If it's a list of things you could get to have a identical element name as well but you will get a redundant xsi:Type attribute:
[XmlRoot("order")]
public class Order
{
private ItemType[] itemTypes;
[XmlElement("ItemType")]
public ItemType[] ItemTypes
{
get { return itemTypes; }
set { itemTypes = value; }
}
}
[XmlInclude(typeof(Clubs))]
[XmlInclude(typeof(Gift))]
public abstract class ItemType
{
private string type = "None";
[XmlAttribute]
public string Type
{
get { return type; }
set { type = value; }
}
}
public class Clubs : ItemType
{
public Clubs()
{
Type = "Clubs";
}
private Club[] clubsArray;
[XmlElement("Club")]
public Club[] ClubsArray
{
get { return clubsArray; }
set { clubsArray = value; }
}
}
public class Club
{
private int num = 0;
[XmlAttribute("num")]
public int Num
{
get { return num; }
set { num = value; }
}
private string clubName = "";
public string ClubName
{
get { return clubName; }
set { clubName = value; }
}
private string clubChoice = "";
public string ClubChoice
{
get { return clubChoice; }
set { clubChoice = value; }
}
}
public class Gift : ItemType
{
public Gift()
{
Type = "Gift";
}
private string val = "";
[XmlAttribute("val")]
public string Val
{
get { return val; }
set { val = value; }
}
private string giftName = "";
public string GiftName
{
get { return giftName; }
set { giftName = value; }
}
private string giftDescription = "";
public string GiftDescription
{
get { return giftDescription; }
set { giftDescription = value; }
}
private int giftQuanity = 0;
public int GiftQuanity
{
get { return giftQuanity; }
set { giftQuanity = value; }
}
}
Test:
List<ItemType> list = new List<ItemType>();
list.Add(new Clubs() { ClubsArray = new Club[] { new Club() { Num = 0, ClubName = "Some Name", ClubChoice = "Something Else" } } });
list.Add(new Gift() { Val = "MailGreeting", GiftName = "MailGreeting", GiftDescription = "GiftDescription", GiftQuanity = 1});
Order order = new Order();
rder.ItemTypes = list.ToArray();
XmlSerializer serializer = new XmlSerializer(typeof(Order));
StreamWriter sw = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Stuff.xml");
serializer.Serialize(sw, order);
sw.Close();
Output:
<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ItemType xsi:type="Clubs" Type="Clubs">
<Club num="0">
<ClubName>Some Name</ClubName>
<ClubChoice>Something Else</ClubChoice>
</Club>
</ItemType>
<ItemType xsi:type="Gift" Type="Gift" val="MailGreeting">
<GiftName>MailGreeting</GiftName>
<GiftDescription>GiftDescription</GiftDescription>
<GiftQuanity>1</GiftQuanity>
</ItemType>
</order>
Related
[Serializable]
public class CampoAuxiliar
{
private string descripcionAuxiliar;
private DateTime fechaAuxiliar;
private ArrayList opcion;
public CampoAuxiliar() { }
[XmlElement(ElementName = "descripcionAuxiliar", Type = typeof(string))]
public string DescripcionAuxiliar
{
get { return descripcionAuxiliar; }
set { descripcionAuxiliar = value; }
}
[XmlElement(ElementName = "fechaHabilitacion", Type = typeof(DateTime))]
public DateTime FechaAuxiliar
{
get { return fechaAuxiliar; }
set { fechaAuxiliar = value; }
}
[XmlArrayItem(ElementName = "opcion", Type = typeof(Opcion))]
[XmlArray(ElementName = "AuxiliarA")]
public ArrayList Opcion
{
get { return opcion; }
set { opcion = value; }
}
}
And this is my xml
- <auxiliarA>
<descripcionAuxiliar>Campo A</descripcionAuxiliar>
<fechaHabilitacion>2017-04-19</fechaHabilitacion>
+ <opcion>
<codigoOpcion>01</codigoOpcion>
<descripcionOpcion>1</descripcionOpcion>
</opcion>
+ <opcion>
<codigoOpcion>02</codigoOpcion>
<descripcionOpcion>2</descripcionOpcion>
</opcion>
+ <opcion>
<codigoOpcion>03</codigoOpcion>
<descripcionOpcion>3</descripcionOpcion>
</opcion>
</auxiliarA>
My problem is I can't figure out how to serialize the "opcion" array into the ArrayList opcion of the class.
With this case it does work and assigns the other nodes properly except for the ArrayList one which returns me count = 0.
You can modify your CampoAuxiliar class as follows:
[XmlRoot("auxiliarA")]
[XmlType("auxiliarA")]
public class CampoAuxiliar
{
private string descripcionAuxiliar;
private DateTime fechaAuxiliar;
public CampoAuxiliar() { }
[XmlElement(ElementName = "descripcionAuxiliar", Type = typeof(string))]
public string DescripcionAuxiliar
{
get { return descripcionAuxiliar; }
set { descripcionAuxiliar = value; }
}
[XmlElement(ElementName = "fechaHabilitacion", Type = typeof(DateTime))]
public DateTime FechaAuxiliar
{
get { return fechaAuxiliar; }
set { fechaAuxiliar = value; }
}
private ArrayList opcion;
[XmlElement("opcion", Type = typeof(Opcion))]
public ArrayList Opcion
{
get { return opcion; }
set { opcion = value; }
}
}
In addition, you should replace the ArrayList with a List<Opcion>:
private List<Opcion> opcion;
[XmlElement("opcion")]
public List<Opcion> Opcion
{
get { return opcion; }
set { opcion = value; }
}
Notes:
[XmlRoot("auxiliarA")] indicates that the root element name is <auxiliarA> not <CampoAuxiliar>.
[XmlElement("opcion")] indicates that the collection is to be serialized without an outer container element.
See ArrayList vs List<> in C# and c# When should I use List and when should I use arraylist? for some discussion of why to prefer List<T> over ArrayList.
Sample fiddle.
I have converted the following two classes to c# from vb.net, but get a reference error. Can someone please help or explain why it does not work in c# but does in vb.net?
Member class:
public class Member
{
#region "Fields"
private string fPiecemark;
private string fMemberType;
private string fSize;
private string fTotalWeight;
private int fSheetKey;
private string fDescription;
private string fStructType;
#endregion
private string fMemberSheetIndex;
#region "Constructors"
//Default class Constructor
public Member()
{
fPiecemark = string.Empty;
fMemberType = string.Empty;
fSize = string.Empty;
fTotalWeight = string.Empty;
fSheetKey = 0;
fStructType = string.Empty;
}
public Member(string Piecemark, string MemberType, string Description, string Size, string TotalWeight, string StructType, string MemberSheetIndex, int SheetID)
{
this.Piecemark = Piecemark;
this.MemberType = MemberType;
this.Description = Description;
this.Size = Size;
this.TotalWeight = TotalWeight;
this.StructType = StructType;
this.MemberSheetIndex = MemberSheetIndex;
this.SheetKey = SheetID;
if (!MbrSheet.mSheet.ContainsKey(SheetID))
{
MbrSheet.mSheet.Add(SheetID, new MbrSheet(SheetID));
}
MbrSheet.mSheets[SheetID].Members.Add(this);
}
#endregion
#region "Properties"
public string Piecemark
{
get { return fPiecemark; }
set { fPiecemark = value; }
}
public string MemberType
{
get { return fMemberType; }
set { fMemberType = value; }
}
public string TotalWeight
{
get { return fTotalWeight; }
set { fTotalWeight = value; }
}
public string Size
{
get { return fSize; }
set { fSize = value; }
}
public int SheetKey
{
get { return fSheetKey; }
set { fSheetKey = value; }
}
public string Description
{
get { return fDescription; }
set { fDescription = value; }
}
public string StructType
{
get { return fStructType; }
set { fStructType = value; }
}
public string MemberSheetIndex
{
get { return fMemberSheetIndex; }
set { fMemberSheetIndex = value; }
}
#endregion
}
MbrSheet class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
public class MbrSheet
{
public static Dictionary<int, MbrSheet> mSheets = new Dictionary<int, MbrSheet>();
public int mSheet { get; set; }
public List<Member> Members { get; set; }
public MbrSheet(int MbrSheet)
{
Members = new List<Member>();
this.mSheet = MbrSheet;
}
public static decimal WeightByType(string MemberType)
{
var subset = mSheets.Where(kvp => kvp.Value.Members.Where(m => m.MemberType == MemberType).Count() > 0);
decimal wbt = 0;
wbt += mSheets
.Where(kvp => kvp.Value.Members.Where(m => m.MemberType == MemberType).Count() > 0)
.Sum(kvp => kvp.Value.Members.Sum(m => Convert.ToDecimal(m.TotalWeight, CultureInfo.InvariantCulture)));
return wbt;
}
}
I get error but don't know why
An object reference is required for the non-static field, method, or property for MbrSheet.mSheet, but both worked in VB.net
if (!MbrSheet.mSheet.ContainsKey(SheetID)) // Error on !MbrSheet.mSheet
{
MbrSheet.mSheet.Add(SheetID, new MbrSheet(SheetID)); // Error on MbrSheet.mSheet
}
I think you should use this:
if (!MbrSheet.mSheets.ContainsKey(SheetID))
{
MbrSheet.mSheets.Add(SheetID, new MbrSheet(SheetID));
}
Pay attention to mSheets you are using mSheet.
You can also use tools to convert codes:
http://www.developerfusion.com/tools/convert/csharp-to-vb/
http://codeconverter.sharpdevelop.net/SnippetConverter.aspx
I have 3 Classes : Masina (Car), Destinatie (Destination) and MasinaDestinatie (CarDestination).
I need the third class to get the values of the car number _nr_masina and the destination _cod_dest through it's own constructor.
I need to make a constructor with parameters in the third class that stores the values of _nr_masina and _cod_dest.
Anyone know how can i do this exactly? I've tried making the private fields public and putting them as parameters but that doesn't work...
The classes:
namespace Problema_test
{
class Masina
{
private string _nr_masina = string.Empty;
private string _valoare = string.Empty;
private string _an_fabricatie = string.Empty;
public Masina(string nr_masina,string valoare, string an_fabricatie)
{
_nr_masina = nr_masina;
_valoare = valoare;
_an_fabricatie = an_fabricatie;
}
public string Numar
{
get { return _nr_masina; }
set { _nr_masina = value; }
}
public string Valoare
{
get { return _valoare; }
set { _valoare = value; }
}
public string Anul
{
get { return _an_fabricatie; }
set { _an_fabricatie = value; }
}
}
class Destinatie
{
private string _cod_destinatie = string.Empty;
private string _adresa = string.Empty;
public Destinatie(string cod_destinatie, string adresa)
{
_cod_destinatie = cod_destinatie;
_adresa = adresa;
}
public string CodDest
{
get { return _cod_destinatie; }
set { _cod_destinatie = value; }
}
public string Adresa
{
get { return _adresa; }
set { _adresa = value; }
}
}
class MasinaDestinatie
{
// how can i make this work?
public MasinaDestinatie(string numarMasina, string codDest)
{
}
}
}
You can store the values inside properties
class MasinaDestinatie
{
public string Numar {get;set;}
public string CodDest {get;set;}
public MasinaDestinatie(string numarMasina, string codDest)
{
Numar = numarMasina;
CodDest = codDest;
}
}
To use the class you have do something like this
var masina = new Masina("Dacia","2000","1992");
var destinatie = new Destinatie("123", "Romania");
var masinaDestinatie = new MasinaDestinatie(masina.Numar, destinatie.CodDest);
Solution 2: As #blas-soriano sugested you can store the reference of the objects (Masina, Destinatie), this way you won't have problems (i.e. CodDest exist only in MasinaDestinatie but not in Destinatie, and many others).
class MasinaDestinatie
{
private Masina _masina {get;set;}
private Destinatie _destinatie {get;set;}
public string Numar { get { return _masina.Numar; } }
public string CodDest { get { return _destinatie.CodDest; } }
public MasinaDestinatie(Masina masina, Destinatie destinatie)
{
_masina = masina;
_destinatie = destinatie;
}
}
To use the class you have do something like this
var masina = new Masina("Dacia","2000","1992");
var destinatie = new Destinatie("123", "Romania");
var masinaDestinatie = new MasinaDestinatie(masina, destinatie);
I have a huge XML file like this:
<Tests>
<Test>
<Code>a</Code>
<Destination>test a</Destination>
<Coordinate>
<Latitude>0.0</Latitude>
<Longitude>0.0</Longitude>
</Coordinate>
<Images>
<ImageURL>1. url 1</ImageURL>
<ImageURL>1. url 2</ImageURL>
<ImageURL>1. url 3</ImageURL>
</Images>
</Test>
<Test>
<Code>b</Code>
<Destination>test b</Destination>
<Coordinate>
<Latitude>0.0</Latitude>
<Longitude>0.0</Longitude>
</Coordinate>
<Images>
<ImageURL>2. url 1</ImageURL>
<ImageURL>2. url 2</ImageURL>
<ImageURL>2. url 3</ImageURL>
<ImageURL>2. url 4</ImageURL>
<ImageURL>2. url 5</ImageURL>
</Images>
</Test>
...
</Tests>
and I try this
reader = XmlReader.Create("file");
while (reader.Read())
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "Test":
{
.....
Test elem = (Test)DeSerializerDestination.Deserialize(reader);
.....
} break;
default: reader.Skip(); break;
}
}
private static readonly XmlSerializer DeSerializerTest = new XmlSerializer(typeof(Test));
public class Test
{
private string _Code = string.Empty;
public string Code
{
get { return _Code; }
set { _Code = value; }
}
private string _Destination = string.Empty;
public string Destination
{
get { return _Destination; }
set { _Destination = value; }
}
private Coordinate _Coordinates = new Coordinate();
public Coordinate Coordinates
{
get { return _Coordinates; }
set { _Coordinates = value; }
}
private ImageUrl[] _ImageUrl;
public ImageUrl[] Images
{
get { return _ImageUrl; }
set { _ImageUrl = value; }
}
}
public class Coordinate
{
private string _Latitude = string.Empty;
public string Latitude
{
get { return _Latitude; }
set { _Latitude = value; }
}
private string _Longitude = string.Empty;
public string Longitude
{
get { return _Longitude; }
set { _Longitude = value; }
}
}
public class ImageUrl
{
private string _ImageURL = string.Empty;
public string ImageURL
{
get { return _ImageURL; }
set { _ImageURL = value; }
}
}
The object elem contains information but not all; property "Images" is always empty.
I think it's because I don't initialize this private ImageUrl[] _ImageUrl;, but would I initialize it, considering I don't know the number of images? I need to mention, I must use .net 2.0.
Update: If I use this in "Images" always I get the first image url.
public class ImageUrl
....
System.Xml.Serialization.XmlElementAttribute("ImageURL")]
public string ImageURL
...
public class Test
...
System.Xml.Serialization.XmlElementAttribute("Images")]
public ImageUrl[] Images
...
Update: I use this
[System.Xml.Serialization.XmlArray("Images")]
[System.Xml.Serialization.XmlArrayItem("ImageURL")]
public List<ImageUrl> Images
{
get { return _ImageUrl; }
set { _ImageUrl = value; }
}
now I get list but "ImageUrl" is empty, do not contain "1. url 1" ....
This is the resolve
[System.Xml.Serialization.XmlIgnore]
private List<string> images = new List<string>();
[System.Xml.Serialization.XmlArray("Images")]
[System.Xml.Serialization.XmlArrayItem("ImageURL")]
public List<string> Images
{
get { return images; }
set { images = value; }
}
Try the following, which will serialize your Xml into your object, providing you object matches your Xml structure.
YourObject oObject = new YourObject ();
try
{
XmlSerializer oSerializer = new XmlSerializer(typeof(YourObject));
using (StringReader oReader = new StringReader(XmlString))
{
oObject = (YourObject)oSerializer.Deserialize(oReader);
}
}
catch
{
...
}
I am parsing a XML file and I want to insert the parsed values into the database,I parsed a set of values and placed in a variable "data". Now I want to pick each values from the variable.Can any one help me,I am a newbie?
The code
XDocument xdoc = XDocument.Parse(e.Result);
var data = from query in xdoc.Descendants("returnData")
select new fieldvalue
{
Authenticated = (String)query.Element("authenticated"),
Repphoto = (String)query.Element("rep_photo"),
Repuname = (String)query.Element("rep_uname"),
Repemail = (String)query.Element("rep_email"),
Repphone = (String)query.Element("rep_phone"),
Repwebsite = (String)query.Element("rep_website"),
Userimgsize = (String)query.Element("user_img_size"),
Usersigsize = (String)query.Element("user_sig_size")
};
The class file
public class fieldvalue
{
String authenticated, rep_photo, rep_uname, rep_email, rep_phone, rep_website, user_img_size, user_sig_size;
public String Authenticated
{
get { return authenticated; }
set { authenticated = value; }
}
public String Repphoto
{
get { return rep_photo; }
set { rep_photo = value; }
}
public String Repuname
{
get { return rep_uname; }
set { rep_uname = value; }
}
public String Repemail
{
get { return rep_email; }
set { rep_email = value; }
}
public String Repphone
{
get { return rep_phone; }
set { rep_phone = value; }
}
public String Repwebsite
{
get { return rep_website; }
set { rep_website = value; }
}
public String Userimgsize
{
get { return user_img_size; }
set { user_img_size = value; }
}
public String Usersigsize
{
get { return user_sig_size; }
set { user_sig_size = value; }
}
}
}
Now I want to pick each values from the variable.
Cast IEnumerable<fieldvalue> result to ToList<> and use index to access each element.
var data = (from query in xdoc.Descendants("returnData")
select new fieldvalue
{
Authenticated = (String)query.Element("authenticated"),
Repphoto = (String)query.Element("rep_photo"),
Repuname = (String)query.Element("rep_uname"),
Repemail = (String)query.Element("rep_email"),
Repphone = (String)query.Element("rep_phone"),
Repwebsite = (String)query.Element("rep_website"),
Userimgsize = (String)query.Element("user_img_size"),
Usersigsize = (String)query.Element("user_sig_size")
}).ToList();
Something like:
var name=data[0].Repuname;