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
{
...
}
Related
I'm having problems trying to get the following XML code to work. First the exception was saying <items xmlns=''> was not expected. and I seem to have been able to fix that by specifying XmlRootAttribute. Now though, it comes back with an empty List<Items> and I can't figure out why. Any ideas?
XML Example
<?xml version="1.0"?>
<items>
<item>
<version>1.0</version>
<title>Example</title>
<changelog>http://example.com/changelog.txt</changelog>
<url>http://www.example.com/download/</url>
</item>
</items>
XML Deserialize Code
Stream appCastStream = webResponse.GetResponseStream();
UpdateXML updateXml = new UpdateXML();
var rootAttribute = new XmlRootAttribute();
rootAttribute.ElementName = "items";
rootAttribute.IsNullable = true;
XmlSerializer serializer = new XmlSerializer(typeof(UpdateXML), rootAttribute);
try
{
using (XmlTextReader reader = new XmlTextReader(appCastStream))
{
if (serializer.CanDeserialize(reader))
{
updateXml = (UpdateXML)serializer.Deserialize(reader);
}
else
{
throw new Exception("Update file is in the wrong format.");
}
}
}
catch (Exception ex)
{
Debug.WriteLine("The following error occurred trying to check for updates: {0}", new object[] { ex.Message });
return;
}
UpdateXML Code
public class UpdateXML
{
public class Item
{
private string _versionString;
private string _title;
private string _changelog;
private string _url;
[XmlElement("version")]
public string VersionString
{
get { return this._versionString; }
set { this._versionString = value; }
}
public Version Version
{
get
{
if (string.IsNullOrEmpty(this._versionString))
return null;
return new Version(this._versionString);
}
}
[XmlElement("title")]
public string Title
{
get { return this._title; }
set { this._title = value; }
}
[XmlElement("changelog")]
public string ChangeLog
{
get { return this._changelog; }
set { this._changelog = value; }
}
[XmlElement("url")]
public string URL
{
get { return this._url; }
set { this._url = value; }
}
}
private List<Item> _items = new List<Item>();
[XmlArray("items")]
[XmlArrayItem("item")]
public List<Item> Items
{
get { return this._items; }
set { this._items = value; }
}
public UpdateXML()
{
}
}
I think the problem is that your XML doesn't really have a "root" element-- the top level element is an array. This answer applied to your problem seems to fix things (also removing the rootAttribute argument passed to the XmlSerializer):
[XmlRootAttribute("items")]
public class UpdateXML
{
private List<Item> _items;
[XmlElement("item")]
public List<Item> Items
{
get { return this._items; }
set { this._items = value; }
}
}
Example: https://dotnetfiddle.net/MAet5y
If you're able to modify the XML, you could add a root element and that would fix the issue as well.
For example, if you wrapped your current XML in <root></root> and then modified your UpdateXML class as follows:
[XmlRootAttribute("root")]
public class UpdateXML
{
private List<Item> _items;
[XmlArray("items")]
[XmlArrayItem("item")]
public List<Item> Items
{
get { return this._items; }
set { this._items = value; }
}
}
Example: https://dotnetfiddle.net/6KfxA4
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;
I have a WCF Service hosted on IIS. Here is my Interface:
[ServiceContract]
[SilverlightFaultBehavior]
public interface IETC
{
[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role = "XYZ")]
string GetStampXML();
[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role = "XYZ")]
List<Stamp> GetStamps();
}
I am getting an error when I go to my WCF service through the web browser. The error is as follows:
Type 'System.Windows.Media.ImageSource' cannot be serialized. Consider marking it with the DataContractAttribute attribute.....
My stamps Class is:
[DataContract]
public class Stamp
{
private string _Name;
private string _SmallIcon = "";
private string _MediumIcon = "";
private string _LargeIcon = "";
private BitmapImage _SmallImage;
private BitmapImage _MediumImage;
private BitmapImage _LargeImage;
[DataMember]
public string Name
{
get { return _Name; }
set { _Name = value; }
}
[DataMember]
public string SmallIcon
{
get { return _SmallIcon; }
set { _SmallIcon = value; }
}
[DataMember]
public string MediumIcon
{
get { return _MediumIcon; }
set { _MediumIcon = value; }
}
[DataMember]
public string LargeIcon
{
get { return _LargeIcon; }
set { _LargeIcon = value; }
}
[IgnoreDataMember]
public BitmapImage SmallImage
{
get { return _SmallImage; }
set { _SmallImage = value; }
}
[IgnoreDataMember]
public BitmapImage MediumImage
{
get { return _MediumImage; }
set { _MediumImage = value; }
}
[IgnoreDataMember]
public BitmapImage LargeImage
{
get { return _LargeImage; }
set { _LargeImage = value; }
}
}
It is like the IgnoreDataMember is not being recognized. I tried it without the IgnoreDataMember figure it was going to only serialize the DataMembers, and that didn't work either. Any ideas why it seems to trying to serialize the BitmapImage?
What version of .net are you running? .NET 4 Data Contract does not require you to explicitly set Ignore attributes. You can test what's being produced by using DataContractSerializer and writing the content to the file. Create console application and reference your service project.
namespace SO_10281928
{
class Program
{
static void Main(string[] args)
{
var instance = new Stamp
{
Name = "Test",
SmallIcon = "Small Icon",
LargeIcon = "LargeIcon",
MediumIcon = "MediumIcon"
};
using (var stream = new FileStream(#"c:\temp\stamp.xml", FileMode.Create))
{
var ds = new DataContractSerializer(typeof (Stamp));
ds.WriteObject(stream, instance);
}
Console.WriteLine("Done.");
Console.ReadLine();
}
}
[DataContract]
public class Stamp
{
private string _Name;
private string _SmallIcon = "";
private string _MediumIcon = "";
private string _LargeIcon = "";
private BitmapImage _SmallImage;
private BitmapImage _MediumImage;
private BitmapImage _LargeImage;
[DataMember]
public string Name
{
get { return _Name; }
set { _Name = value; }
}
[DataMember]
public string SmallIcon
{
get { return _SmallIcon; }
set { _SmallIcon = value; }
}
[DataMember]
public string MediumIcon
{
get { return _MediumIcon; }
set { _MediumIcon = value; }
}
[DataMember]
public string LargeIcon
{
get { return _LargeIcon; }
set { _LargeIcon = value; }
}
public BitmapImage SmallImage
{
get { return _SmallImage; }
set { _SmallImage = value; }
}
public BitmapImage MediumImage
{
get { return _MediumImage; }
set { _MediumImage = value; }
}
public BitmapImage LargeImage
{
get { return _LargeImage; }
set { _LargeImage = value; }
}
}
public class BitmapImage
{
}
}
And the result is :
<Stamp xmlns="http://schemas.datacontract.org/2004/07/SO_10281928" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<LargeIcon>LargeIcon</LargeIcon>
<MediumIcon>MediumIcon</MediumIcon>
<Name>Test</Name>
<SmallIcon>Small Icon</SmallIcon>
</Stamp>
I am trying to deserialize an XML file to a class. The XML file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<locations>
<location id="0">
<name>park</name>
<temperature>5</temperature>
<wind>26</wind>
<weather_text_SI>sunny</weather_text_SI>
<visibility></visibility>
<latitude>46.4527</latitude>
<longitude>15.334</longitude>
<elevation>1517</elevation>
</location>
</locations>
The class that I want to deserialize it to is:
[XmlRootAttribute("locations")]
public class SnowPark
{
public SnowPark()
{
}
private int id;
[XmlAttribute("id")]
public int Id
{
get { return id; }
set { id = value; }
}
private string name;
[XmlElement("name")]
public string Name
{
get { return name; }
set { name = value; }
}
private int temperature;
[XmlElement("temperature")]
public int Temperature
{
get { return temperature; }
set { temperature = value; }
}
private int wind;
[XmlElement("wind")]
public int Wind
{
get { return wind; }
set { wind = value; }
}
private string weatherText;
[XmlElement("weather_text_SI")]
public string WeatherText
{
get { return weatherText; }
set { weatherText = value; }
}
private double latitude;
[XmlElement("latitude")]
public double Latitude
{
get { return latitude; }
set { latitude = value; }
}
private double longitude;
[XmlElement("longitude")]
public double Longitude
{
get { return longitude; }
set { longitude = value; }
}
private int elevation;
[XmlElement("elevation")]
public int Elevation
{
get { return elevation; }
set { elevation = value; }
}
}
I try to deserialize the XML file
XmlSerializer deserializer = new XmlSerializer(typeof(List<SnowPark>));
TextReader textReader = new StreamReader(#"file.xml");
List<SnowPark> parks;
parkss = (List<SnowPark>)deserializer.Deserialize(textReader);
textReader.Close();
However I get an exception:
There is an error in XML document (2, 2).
and an inner exception:
<locations xmlns=''> was not expected.
No luck finding the solution so far. Help appreciated.
The XmlRootAttribute doesn't apply since you are serialising a list of then, not an individual item; this also means your XML is one layer further-out than needed.
IMO, your easiest option here is:
[XmlRoot("locations")]
public class Locations
{
[XmlElement("location")]
public List<SnowPark> Parks {get;set;}
}
and deserialize a Locations object, using typeof(Locations) to initialisers the XmlSerializer
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>