How to get value from element attribute, XML Serialization - c#

I want to get an attribute from vimeo xml.. here is structure of xml document
<?xml version="1.0" encoding="UTF-8" ?>
- <rsp generated_in="0.6533" stat="ok">
- <videos on_this_page="15" page="1" perpage="15" total="329">
- <video allow_adds="1" embed_privacy="anywhere" id="3475223" is_hd="0" is_transcoding="0" license="0" privacy="anybody">
<title>AxDroid - Android on Dell Axim x51v</title>
<description>This is my first attempt at installing and running Android on my Dell Axim x51v. Touchscreen and buttons are working! For details please visit: http://axdroid.blogspot.com/</description>
<upload_date>2009-03-04 16:14:19</upload_date>
<modified_date>2012-07-14 07:03:32</modified_date>
<number_of_likes>2</number_of_likes>
<number_of_plays>43422</number_of_plays>
<number_of_comments>1</number_of_comments>
<width>320</width>
<height>240</height>
<duration>320</duration>
- <owner display_name="Ertan D." id="1387509" is_plus="0" is_pro="0" is_staff="0" profileurl="http://vimeo.com/user1387509" realname="Ertan D." username="user1387509" videosurl="http://vimeo.com/user1387509/videos">
- <portraits>
<portrait height="30" width="30">http://a.vimeocdn.com/images_v6/portraits/portrait_30_yellow.png</portrait>
<portrait height="75" width="75">http://a.vimeocdn.com/images_v6/portraits/portrait_75_yellow.png</portrait>
<portrait height="100" width="100">http://a.vimeocdn.com/images_v6/portraits/portrait_100_yellow.png</portrait>
<portrait height="300" width="300">http://a.vimeocdn.com/images_v6/portraits/portrait_300_yellow.png</portrait>
</portraits>
</owner>
- <tags>
<tag author="1387509" id="8397224" normalized="android" url="http://vimeo.com/tag:android">android</tag>
<tag author="1387509" id="8397225" normalized="dell" url="http://vimeo.com/tag:dell">dell</tag>
<tag author="1387509" id="8397226" normalized="axim" url="http://vimeo.com/tag:axim">axim</tag>
<tag author="1387509" id="8397227" normalized="linux" url="http://vimeo.com/tag:linux">linux</tag>
<tag author="1387509" id="8397228" normalized="google" url="http://vimeo.com/tag:google">google</tag>
<tag author="1387509" id="8397229" normalized="pda" url="http://vimeo.com/tag:pda">pda</tag>
<tag author="1387509" id="8397230" normalized="ppc" url="http://vimeo.com/tag:ppc">ppc</tag>
</tags>
- <cast>
<member display_name="Ertan D." id="1387509" role="" username="user1387509" />
</cast>
- <urls>
<url type="video">http://vimeo.com/3475223</url>
</urls>
- <thumbnails>
<thumbnail height="75" width="100">http://b.vimeocdn.com/ts/347/807/3478071_100.jpg</thumbnail>
<thumbnail height="150" width="200">http://b.vimeocdn.com/ts/347/807/3478071_200.jpg</thumbnail>
<thumbnail height="480" width="640">http://b.vimeocdn.com/ts/347/807/3478071_640.jpg</thumbnail>
</thumbnails>
</video>
- <video allow_adds="1" embed_privacy="anywhere" id="28665952" is_hd="1" is_transcoding="0" license="0" privacy="anybody">
<title>Duygu + Ertan Şıkır Şıkır by DÜĞÜNHİKAYEMİZ</title>
<description />
<upload_date>2011-09-06 10:54:49</upload_date>
<modified_date>2012-07-14 06:41:33</modified_date>
<number_of_likes>3</number_of_likes>
<number_of_plays>26214</number_of_plays>
and I want to get username attribute from owner element. Here is serialization code.
[XmlTypeAttribute(AnonymousType = true)]
[XmlRootAttribute(Namespace = "", IsNullable = false, ElementName = "rsp")]
public partial class VimeoSearchResponse
{
private SearchResponseVideosWrapper _videos;
private string _generated_in;
private string _stat;
[XmlElementAttribute("videos", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public SearchResponseVideosWrapper videos
{
get { return _videos; }
set { _videos = value; }
}
[XmlAttributeAttribute()]
public string generated_in
{
get { return _generated_in; }
set { _generated_in = value; }
}
[XmlAttributeAttribute()]
public string stat
{
get { return _stat; }
set { _stat = value; }
}
}
[SerializableAttribute]
[XmlTypeAttribute(AnonymousType = true)]
public partial class SearchResponseVideosWrapper
{
private SearchResponseVideosWrapperVideo[] _video;
private string _on_this_page;
private string _page;
private string _perpage;
private string _total;
[XmlElementAttribute("video", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public SearchResponseVideosWrapperVideo[] video
{
get { return _video; }
set { _video = value; }
}
[XmlAttributeAttribute()]
public string on_this_page
{
get { return _on_this_page; }
set { _on_this_page = value; }
}
[XmlAttributeAttribute()]
public string page
{
get { return _page; }
set { _page = value; }
}
[XmlAttributeAttribute()]
public string perpage
{
get { return _perpage; }
set { _perpage = value; }
}
[XmlAttributeAttribute()]
public string total
{
get { return _total; }
set { _total = value; }
}
}
[SerializableAttribute]
[XmlTypeAttribute(AnonymousType = true)]
public partial class SearchResponseVideosWrapperVideo
{
private string _title;
private string _id;
private string _username;
[XmlElement()]
public string title
{
get { return _title; }
set { _title = value; }
}
[XmlAttributeAttribute()]
public string id
{
get { return _id; }
set { _id = value; }
}
[XmlElementAttribute("owner")]
public string username
{
get { return _username; }
set { _username = value; }
}
}
problem is here i think
[XmlElementAttribute("owner")]
public string username
{
get { return _username; }
set { _username = value; }
}
- <owner display_name="Ertan D." id="1387509" is_plus="0" is_pro="0" is_staff="0" profileurl="http://vimeo.com/user1387509" realname="Ertan D." username="user1387509" videosurl="http://vimeo.com/user1387509/videos">
how can I get attribute from owner..
here is exception detail
I get an exception that is There is an error in XML document (1,
1005).
{"Unexpected node type Element. ReadElementString method can only be
called on elements with simple or empty content. Line 1, position
1005."}
System.InvalidOperationException was caught

You need an 'owner' class. You also might consider adding the 'portrait' class with a collection in the 'owner' class.
public class owner
{
[XmlAttributeAttribute]
public string username { get; set; }
}
[SerializableAttribute]
[XmlTypeAttribute(AnonymousType = true)]
public partial class SearchResponseVideosWrapperVideo
{
private string _title;
private string _id;
private string _username;
[XmlElement()]
public string title
{
get { return _title; }
set { _title = value; }
}
[XmlAttributeAttribute()]
public string id
{
get { return _id; }
set { _id = value; }
}
[XmlElementAttribute("owner")]
public owner owner { get; set; }
}

You are annotating username with an XmlElementAttribute for "owner."
That implies that the owner element should be deserialized into the string property username.
If you want to get at username, you first have to deserialize owner into some object.
For example, you could add an Owner class, in the same manner as you created VimeoSearchResponse.
public class Owner
{
private string _owner;
[XmlAttribute]
public string username
{
get { return _owner; }
set { _owner = value; }
}
}

Related

Get Value from XML tag

I have the following code:
p.tel.FirstOrDefault(t => t.teltype == "mobile").ToString()
<person>
<name>Donald Duck</name>
<tel teltype="voice" />
<tel teltype="mobile">01000000</tel>
</person>
The c# class for the xml look like this:
[System.Xml.Serialization.XmlElementAttribute("tel")]
public enterprisePersonTel[] tel {
get {
return this.telField;
}
set {
this.telField = value;
}
}
My code returns: enterprisePersonTel
This doesn't work
p.tel.FirstOrDefault(t => t.teltype == "mobile").Value
How can I get the actual telephone number?
The class for the attribute was not generated correctly
public partial class enterprisePersonTel
{
private string teltypeField;
private string valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string teltype
{
get
{
return this.teltypeField;
}
set
{
this.teltypeField = value;
}
}
/// <remarks/>
**[System.Xml.Serialization.XmlTextAttribute()]
public string Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}**
}
The ** part of the text was missing when using paste as class in Visual studio.

How to deserialize element that can be single or array?

Got XML that i want to deserialize to Object.
There is no questions if i deserialize only non-multiple value element, but i got no idea what to do with an array of value elements in value element.
There is always UnknownNode with LocalName = #text,
XML to deserialize
<?xml version="1.0" encoding="UTF-8"?>
<issue>
<custom_fields type="array">
<custom_field id="11" name="Version">
<value>7.9.18.31</value>
</custom_field>
<custom_field id="89" name="Tags" multiple="true">
<value type="array">
<value>Tag1</value>
<value>Tag3</value>
<value>Tag6</value>
</value>
</custom_field>
<custom_field id="90" name="started_on">
<value>2017-08-25</value>
</custom_field>
</custom_fields>
</issue>
class i get with xsd.exe
using System.Xml.Serialization;
[XmlRoot(IsNullable=false)]
public partial class issue
{
private object[] itemsField;
[XmlElement("custom_fields", typeof(issueCustom_fields))]
[XmlElement("value", typeof(Value))]
public object[] Items
{
get { return itemsField; }
set { itemsField = value; }
}
}
public class Value
{
private Value[] valueField;
private string typeField;
[XmlElement("value")]
public Value[] value
{
get { return valueField; }
set { valueField = value; }
}
[XmlAttribute]
public string type
{
get { return typeField; }
set { typeField = value; }
}
}
public class issueCustom_fields
{
private issueCustom_fieldsCustom_field[] custom_fieldField;
private string typeField;
[XmlElement("custom_field")]
public issueCustom_fieldsCustom_field[] custom_field
{
get { return custom_fieldField; }
set { custom_fieldField = value; }
}
[XmlAttribute]
public string type
{
get { return typeField; }
set { typeField = value; }
}
}
public class issueCustom_fieldsCustom_field
{
private Value[] valueField;
private string idField;
private string nameField;
private string multipleField;
[XmlElement("value")]
public Value[] value
{
get { return valueField; }
set { valueField = value; }
}
[XmlAttribute]
public string id
{
get { return idField; }
set { idField = value; }
}
[XmlAttribute]
public string name
{
get { return nameField; }
set { nameField = value; }
}
[XmlAttribute]
public string multiple
{
get { return multipleField; }
set { multipleField = value; }
}
}
Deserializing code
var ser = new XmlSerializer(typeof(issue));
var issue = new issue();
using (var sr = new StreamReader("testIssues.xml"))
issue = (issue)ser.Deserialize(sr);
i can get data using:
ser.UnknownNode += (s, ea) =>
{
if (ea.LocalName == "#text" && ea.ObjectBeingDeserialized is Value)
{
Value val = (Value)ea.ObjectBeingDeserialized;
if (val.value == null)
{
val.Val = ea.Text;
}
}
};
but is there a way to get it more smoothe way using just deserialization?
Have you tried to use XmlArrayAttribute?
[XmlArray("value")]
public Value[] Items
{
get { return itemsField; }
set { itemsField = value; }
}
[XmlType("Value")]
public class Value
{
....
}
Check out this question.

Cannot define more than one section in web.config

I want to have multiple sections in sectiongroup like this
**<CredentialsGroup>
<Credentials>
<company name="Carolina" userid="abc" password="dd"></company>
<file name="dfbf0f94-767e-4c71-b4ee-2dc05fb76e3c.csv"
url="https://e.brightree.net/Home/file.csv"></file>
<company name="Asbury" userid="abc" password="dde"></company>
<file name="dfbf0f94-767e-4c71-b4ee-2dc05fb76e3c.csv"
url="https://e.brightree.net/Home/file.csv"></file>
</Credentials>
</CredentialsGroup>**
and this is my customconfig File
**public class CredentialsSection: ConfigurationSection
{
[ConfigurationProperty("company",IsRequired=true)]
public CompanyElement Company
{
get {
return (CompanyElement)this["company"];
}
set
{
this["company"] = value;
}
}
[ConfigurationProperty("file",IsRequired=true)]
public FileElement File
{
get
{
return (FileElement)this["file"];
}
set
{
this["file"] = value;
}
}
}
public class CompanyElement : ConfigurationElement
{
[ConfigurationProperty("name",IsRequired=true)]
public string Name
{
get {
return (string)this["name"];
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("userid", IsRequired = true)]
public string UserId
{
get
{
return (string)this["userid"];
}
set
{
this["userid"] = value;
}
}
[ConfigurationProperty("password", IsRequired = true)]
public string Password
{
get
{
return (string)this["password"];
}
set
{
this["password"] = value;
}
}
}
public class FileElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("url",IsRequired=true)]
public string Url
{
get
{
return (string)this["url"];
}
set {
this["url"] = value;
}
}
}**
Company and File node shoukd be siblings and their selection will be conditional based on company name like this
ConfigurationManager.GetSection("CredentialsGroup/Credentials/company['name']=" + companyName);
Please Help

Deserialize xml element attributes

I'm admittedly learning here, and have made progress in serializing and deserialzing xml.
Question that I have is, how do I access the URI in the XML below?
<address href="/api/juniper/sd/address-management/addresses/98677"
uri="/api/juniper/sd/address-management/addresses/98677">
<name>Any-IPv4</name>
<address-type>ANY_IPV4</address-type>
<description>Predefined any-ipv4 address</description>
<host-name />
<id>98677</id>
</address>
Really not sure how to set that up in my class to deserialize it?
My class right now looks like:
[XmlRoot("address", Namespace = "")]
public class address
{
string _name;
string _editVersion;
string _addressType;
string _ipAddress;
string _description;
string _hostName;
string _zone;
string _addressVersion;
string _definitionType;
string _createdByUserName;
string _lastModifiedByUser;
string _createdTime;
string _lastModifiedTime;
string _id;
[XmlElement(ElementName = "name")]
public string name
{
get { return _name; }
set { _name = value; }
}
[XmlElement(ElementName = "edit-version")]
public string editversion
{
get { return _editVersion; }
set { _editVersion = value; }
}
[XmlElement(ElementName = "address-type")]
public string addresstype
{
get { return _addressType; }
set { _addressType = value; }
}
[XmlElement(ElementName = "ip-address")]
public string ipaddress
{
get { return _ipAddress; }
set { _ipAddress = value; }
}
[XmlElement(ElementName = "description")]
public string description
{
get { return _description; }
set { _description = value; }
}
[XmlElement(ElementName = "host-name")]
public string hostname
{
get { return _hostName; }
set { _hostName = value; }
}
}
Thanks in advance!
Use the XmlAttributeAttribute attribute*
[XmlAttribute]
public string uri
{
get { return _uri; }
set { _uri = value; }
}
If you want to have it serialize it as System.Uri, you'll have to do it with a separate property as Uri is non-serializable.
[XmlAttribute("uri")]
public string SerializedUri
{
get
{
return uri.ToString();
}
set
{
uri = new Uri(value, UriKind.RelativeOrAbsolute);
}
}
[XmlIgnore]
public Uri uri { get; set; }
With this usage, in-code you would read/write directly to the Uri uri property and ignore the SerializedUri property. When passed through the serializer it will ignore that property and instead use the SerializedProperty which will in turn manually serialize/deserialize the Uri uri property.
* (say that 3 times fast)

Newtonsoft.Json : Cant get JSON data to convert into C# Object

Call to a REST based API returns me data in JSON format(stored in variable strJSONStringFromAPI).
{
"id": "551",
"name": "Dev D",
"work": [
{
"employer": {
"name": "Microsoft Corporation"
},
"position": {
"name": "Software Development"
}
}
],
"gender": "male"}
I have created following classes corresponding to above JSON data
public class Employer
{
private string _name;
public string name
{
get { return _name; }
set { _name = value; }
}
}
public class Position
{
private string _name;
public string name
{
get { return _name; }
set { _name = value; }
}
}
public class Work
{
private Employer _employer;
private Position _position;
public Employer employer
{
get { return _employer; }
set { _employer = value; }
}
public Position position
{
get { return _position; }
set { _position = value; }
}
}
public class UserInfo
{
private string _id;
private string _name;
private Work[] _wk;
public string id
{
get { return _id; }
set { _id = value; }
}
public string name
{
get { return _name; }
set { _name = value; }
}
public Work[] work
{
get { return _wk; }
set { _wk = value; }
}
}
Now i have method GetUserInfo which should return object UserInfo as shown below
Public UserInfo GetUserDetails()
{
UserInfo user = New UserInfo();
user = Newtonsoft.Json.JsonConvert.DeserializeObject<UserInfo>(strJSONStringFromAPI);
return user;
}
later i will access the values as
label1.text = user.ID ;
label2.text = user.name;
As of now i am getting all properties of above user object as NULL (user.ID = null etc etc)
I know i am missing something very important here..can someone help me what else needs to be done in in Employer , Position and Work classes so that i get proper values (eg user.ID = "551" etc)
Your Work class above will not compile.
public class Work
{
private Employer _employer;
private Position _position;
public Employer employer
{
get { return _employer; }
set { _employer = value; }
}
public Position position
{
get { return _employer; }
set { _employer = value; }
}
}
The Position property can't use _employer.
Tested your code with that corrected, it does work as expected. Here's a simple test using a HTTP Handler:
<%# WebHandler Language="C#" Class="JsonDotnet" %>
using System;
using System.IO;
using System.Web;
using Newtonsoft.Json;
public class JsonDotnet : IHttpHandler {
public void ProcessRequest (HttpContext context) {
string json = context.Server.MapPath(
"~/app_data/json-test.txt"
);
UserInfo user = Newtonsoft.Json.JsonConvert
.DeserializeObject<UserInfo>(
File.ReadAllText(json)
);
context.Response.Write(user.id + "<br>");
context.Response.Write(user.name + "<br>");
context.Response.Write(user.work[0].employer.name + "<br>");
}
public bool IsReusable {
get { return false; }
}
public class Employer {
public string name { get; set;}
}
public class Position {
public string name { get; set;}
}
public class Work {
public Employer employer { get; set;}
public Position position { get; set;}
}
public class UserInfo {
public string id { get; set;}
public string name { get; set;}
public Work[] work { get; set;}
}
}
Don't forget to put your json string in ~/app_data/json-test.txt.
Are you sure strJSONStringFromAPI is exactly the same as the string you specified in your first code snippet above?
Your private variable should be public when you deserialize the json object and all name should be same in both in json object as well as in classes

Categories