I am trying to deserialize activity into object type activities according to the RFC (converted XSD to C# class using the XSD in the RFC), but it seems like I'm encountering issues with the activity xml element, since it is containing a inner namespace in the attribute.
XML:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<presence xmlns="urn:ietf:params:xml:ns:pidf" entity="sip:anon#domain.invalid" xmlns:e="urn:ietf:params:xml:ns:pidf:status:rpid" xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:ce="urn:cisco:params:xml:ns:pidf:rpid" xmlns:sc="urn:ietf:params:xml:ns:pidf:servcaps">
<dm:person>
<status>
<basic>open</basic>
</status>
<e:activities>
</e:activities>
</dm:person>
</presence>
I am deserializing this into a presence object, take the first (presence.Any[0]), and deserialize this into a person object, everything is fine so far. But then I want to take the activity element from person, and deserialize this:
person.Any.SingleOrDefault(x => x.LocalName == "activities")
But now the XML of that object looks like:
<e:activities xmlns:e="urn:ietf:params:xml:ns:pidf:status:rpid">
</e:activities>
And if I try to deserialize this into a activities object as of XSD in RFC3863, I'm ending with the following error message:
Message "<activities xmlns='urn:ietf:params:xml:ns:pidf:status:rpid'> was not expected."
How do I deserialize XmlElements that contains a inner namespace like this??
UPDATE 23-11-17 (Elements which is empty):
XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:pp="urn:ietf:params:xml:ns:pidf:person" xmlns:es="urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status" xmlns:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person" entity="sip:Alice#10.24.18.124">
<pp:person>
<status>
<ep:activities>
<ep:away/>
</ep:activities>
</status>
</pp:person>
<note>Unavailable</note>
<tuple id="6001">
<contact priority="1">sip:6001#10.24.18.124</contact>
<status>
<basic>closed</basic>
</status>
</tuple>
</presence>
Problem:
<ep:away xmlns:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person" />
Data Entities:
[XmlType(TypeName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
public class Activities : activities
{
[XmlElement(Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
public ItemsChoiceType State { get; set; }
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:ietf:params:xml:ns:pidf:rpid", IncludeInSchema=false)]
public enum ItemsChoiceType {
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("##any:")]
Item,
/// <remarks/>
appointment,
/// <remarks/>
away,
/// <remarks/>
breakfast,
/// <remarks/>
busy,
/// <remarks/>
dinner,
/// <remarks/>
holiday,
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("in-transit")]
intransit,
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("looking-for-work")]
lookingforwork,
/// <remarks/>
meal,
/// <remarks/>
meeting,
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("on-the-phone")]
onthephone,
/// <remarks/>
other,
/// <remarks/>
performance,
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("permanent-absence")]
permanentabsence,
/// <remarks/>
playing,
/// <remarks/>
presentation,
/// <remarks/>
shopping,
/// <remarks/>
sleeping,
/// <remarks/>
spectator,
/// <remarks/>
steering,
/// <remarks/>
travel,
/// <remarks/>
tv,
/// <remarks/>
unknown,
/// <remarks/>
vacation,
/// <remarks/>
working,
/// <remarks/>
worship,
}
You have to declare the namespaces correctly, especially the default namespaces. See working code below :
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 INPUT_FILENAME = #"c:\temp\test.xml";
const string OUTPUT_FILENAME = #"c:\temp\test1.xml";
static void Main(string[] args)
{
Presence outPresence = new Presence()
{
person = new Person()
{
status = new Status()
{
basic = "test"
},
activities = new Activities()
{
}
}
};
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("dm", "urn:ietf:params:xml:ns:pidf:data-model");
xmlNameSpace.Add("e", "urn:ietf:params:xml:ns:pidf:status:rpid");
xmlNameSpace.Add("", "");
XmlSerializer serializer = new XmlSerializer(typeof(Presence), "urn:ietf:params:xml:ns:pidf");
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME, settings);
serializer.Serialize(writer, outPresence, xmlNameSpace);
StreamReader reader = new StreamReader(INPUT_FILENAME);
Presence presense = (Presence)serializer.Deserialize(reader);
}
}
[XmlRoot(ElementName = "presence")]
public class Presence
{
[XmlElement(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:data-model")]
public Person person { get; set; }
}
[XmlRoot(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:data-model")]
public class Person
{
[XmlElement(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
public Status status { get; set; }
[XmlElement(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:status:rpid")]
public Activities activities { get; set; }
}
[XmlRoot(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
public class Status
{
[XmlElement("basic")]
public string basic { get; set; }
}
[XmlRoot(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:status:rpid")]
public class Activities
{
}
}
Updated code 11/23/17
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 INPUT_FILENAME = #"c:\temp\test.xml";
const string OUTPUT_FILENAME = #"c:\temp\test1.xml";
static void Main(string[] args)
{
Presence outPresence = new Presence()
{
person = new Person()
{
status = new Status()
{
basic = "test",
activities = new Activities()
{
}
},
}
};
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("pp", "urn:ietf:params:xml:ns:pidf:person");
xmlNameSpace.Add("ep", "urn:ietf:params:xml:ns:pidf:rpid:rpid-person");
xmlNameSpace.Add("", "urn:ietf:params:xml:ns:pidf");
XmlSerializer serializer = new XmlSerializer(typeof(Presence), "urn:ietf:params:xml:ns:pidf");
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME, settings);
serializer.Serialize(writer, outPresence, xmlNameSpace);
StreamReader reader = new StreamReader(INPUT_FILENAME);
Presence presense = (Presence)serializer.Deserialize(reader);
}
}
[XmlRoot(ElementName = "presence")]
public class Presence
{
[XmlElement(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:person")]
public Person person { get; set; }
}
[XmlRoot(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:person")]
public class Person
{
[XmlElement(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
public Status status { get; set; }
}
[XmlRoot(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
public class Status
{
[XmlElement("basic")]
public string basic { get; set; }
[XmlElement(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
public Activities activities { get; set; }
}
[XmlRoot(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
public class Activities
{
[XmlElement("away")]
public string away { get; set; }
}
}
Related
To consume a SOAP service, I need to send messages in XML which looks like:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:bus="http://ws.praxedo.com/v6/businessEvent">
<soap:Header/>
<soap:Body>
<bus:listAttachments>
<businessEventId>00044</businessEventId>
</bus:listAttachments>
</soap:Body>
</soap:Envelope>
Obviously, the easy way to do this would just be to create a string and interpolate some variable (e.g. businessEventId) into the midst of it, like:
$"<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\""
+ " xmlns:bus=\"http://ws.praxedo.com/v6/businessEvent\">"
+ "<soap:Header/><soap:Body>"
+ "<bus:listAttachments><businessEventId>{businessEventId}</businessEventId>"
+ "</bus:listAttachments></soap:Body></soap:Envelope>"
But I'd rather instantiate some collection of POPO, like:
public class Envelope {
public Header Header {get; init;}
public Body Body {get; init;}
}
public class Header {
}
public class Body {
public ListAttachments Attachments {get; init;}
}
public class ListAttachments {
public string BusinessEventId {get; init;}
}
What Attributes do I need to declare?
And what would I then need to do to serialize this, assuming I have a populated instance already?
--
As per #DavidBrowne's comment, I've tried the following which does NOT work:
private string CreateBody(string businessEventId)
{
BusinessEventAttachmentListRequestEnvelope envelope = BusinessEventAttachmentListRequestEnvelope.From(businessEventId);
MemoryStream memorystream = new();
DataContractSerializer serializer = new(typeof(BusinessEventAttachmentListRequestEnvelope));
serializer.WriteObject(memorystream, envelope);
memorystream.Seek(0, SeekOrigin.Begin);
using StreamReader streamReader = new(memorystream);
return streamReader.ReadToEnd();
}
[DataContract(Name = "Envelope", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class BusinessEventAttachmentListRequestEnvelope
{
[DataMember]
EmptySoapHeader Header = new();
[DataMember]
BusinessEventAttachmentListRequestBody Body { get; init; }
public static BusinessEventAttachmentListRequestEnvelope From(string businessEventId) =>
new()
{
Body = new()
{
Request = new()
{
BusinessEventId = businessEventId
}
}
};
}
[DataContract(Name = "Header", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class EmptySoapHeader
{
}
[DataContract(Name = "Body", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class BusinessEventAttachmentListRequestBody
{
[DataMember(Name = "listAttachments")]
public BusinessEventAttachmentListRequest Request { get; init; }
}
[DataContract(Name = "listAttachments", Namespace = "http://ws.praxedo.com/v6/businessEvent")]
public class BusinessEventAttachmentListRequest
{
[DataMember(Name = "businessEventId")]
public string BusinessEventId { get; init; }
}
The resulting XML seems substantially different:
<Envelope xmlns=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">
<Body>
<listAttachments xmlns:a=\"http://ws.praxedo.com/v6/businessEvent\">
<a:businessEventId>00044</a:businessEventId>
</listAttachments>
</Body>
<Header/>
</Envelope>
And the remote server returns error 500.
If you're using Visual Studio there's a really easy shortcut you can use: Paste XML as Classes:
Which creates for your sample XML:
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2003/05/soap-envelope", IsNullable = false)]
public partial class Envelope
{
private object headerField;
private EnvelopeBody bodyField;
/// <remarks/>
public object Header
{
get
{
return this.headerField;
}
set
{
this.headerField = value;
}
}
/// <remarks/>
public EnvelopeBody Body
{
get
{
return this.bodyField;
}
set
{
this.bodyField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public partial class EnvelopeBody
{
private listAttachments listAttachmentsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace = "http://ws.praxedo.com/v6/businessEvent")]
public listAttachments listAttachments
{
get
{
return this.listAttachmentsField;
}
set
{
this.listAttachmentsField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://ws.praxedo.com/v6/businessEvent")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://ws.praxedo.com/v6/businessEvent", IsNullable = false)]
public partial class listAttachments
{
private byte businessEventIdField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace = "")]
public byte businessEventId
{
get
{
return this.businessEventIdField;
}
set
{
this.businessEventIdField = value;
}
}
}
My current XML response is as shown below(only important parts are shown).I have added service reference which have generated some proxy classes for me which unfortunately are not returning the output as needed.The c# code below only return the last "values" data. What i eventually want is to have arrays of "values" that i will display in a gridview.
<return>
<fields></fields>
<fields></fields>
<fields></fields>
<values>
<value></value>
<value></value>
<value></value>
</values>
<values>
<value></value>
<value></value>
<value></value>
</values>
//proxy class
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3056.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://ws.server.mhaccess.crimsonlogic.com/")]
public partial class qwsOutput : baseWebServiceOutput {
private string[] fieldsField;
public List<string> values { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("fields", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true, Order=0)]
public string[] fields {
get {
return this.fieldsField;
}
set {
this.fieldsField = value;
this.RaisePropertyChanged("fields");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = true, Order = 1)]
[System.Xml.Serialization.XmlArrayItemAttribute("value", typeof(string[]), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public List<string> value
{
get
{
return this.values;
}
set
{
this.values = value;
this.RaisePropertyChanged("values");
}
}
}
//code use to call soap request
SoapService.queryWebServiceSoapPortClient client = new
SoapService.queryWebServiceSoapPortClient();
client.ClientCredentials.UserName.UserName = userID;
client.ClientCredentials.UserName.Password = Password;
SoapService.qwsInput query1 = new SoapService.qwsInput();
SoapService.queryResponse response = new
SoapService.queryResponse();
query1.userId = userID;
query1.pass = Password;
query1.queryId = queryId;
query1.qwsInputParams = InputParam;
query a = new query();
a.queryInput = query1;
try
{
response = client.query(a);
}
catch (Exception error)
{
var b = error.ToString();
}
//updated code
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3056.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://ws.server.mhaccess.crimsonlogic.com/")]
public partial class qwsOutput : baseWebServiceOutput {
private string[] fieldsField;
//private string[][] valuesField;
private object[] valuesField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("fields", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true, Order=0)]
public string[] fields {
get {
return this.fieldsField;
}
set {
this.fieldsField = value;
this.RaisePropertyChanged("fields");
}
}
///// <remarks/>
//[System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true, Order=1)]
//[System.Xml.Serialization.XmlArrayItemAttribute("values", typeof(returnValues), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlElementAttribute("values", typeof(returnValues), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 1)]
public object[] values {
get {
return this.valuesField;
}
set {
this.valuesField = value;
//this.RaisePropertyChanged("values");
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class returnValues
{
private returnValuesValue[] valueField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("value", Form =
System.Xml.Schema.XmlSchemaForm.Unqualified)]
public returnValuesValue[] value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class returnValuesValue
{
}
I tested following code and it works :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication110
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
StringReader reader = new StringReader(xml);
XmlSerializer serializer = new XmlSerializer(typeof(Return));
Return _return = (Return)serializer.Deserialize(reader);
}
}
[XmlRoot("return")]
public class Return
{
[XmlElement("fields")]
public List<string> fields { get; set; }
[XmlElement("values")]
public List<Value> values { get; set; }
}
[XmlRoot("value")]
public class Value
{
[XmlElement("value")]
public List<string> value { get; set; }
}
}
I would like to be able to 'do things' to the Vehicles in the XML file. Ideally I want to iterate through all the vehicles and do a calculation on their price, and change whether they are OnSale. These values would then be displayed in the UI. My code deserializes the XML file but I am unable to access any of the attributes for the Vehicle. I do not need to serialize the objects back to XML.
I have tried to Console.WriteLine the Price, however when I run the code it is returned as 0. Should I be creating an Array of ResponseGeographyVendorRegionVehicle? and then somehow adding objects of that type to the array?
This is the XML File:
<?xml version="1.0" encoding="utf-8" ?>
<Response>
<Geography>
<Vendor id="JOHN">
<Region id="1"></Region>
<Region id="2">
<Vehicle Make="HONDA" Fuel="Gas" Price="12000" OnSale="Y" Account="JOHNH" />
<Vehicle Make="ACURA" Fuel="Gas" Price="14100" OnSale="Y" Account="JOHNH" />
<Vehicle Make="TOYOTA" Fuel="Gas" Price="8000" OnSale="N" Account="JOHNH" />
<Vehicle Make="HYUNDAI" Fuel="Gas" Price="13000" OnSale="Y" Account="JOHNH" />
<Vehicle Make="INFINITY" Fuel="Gas" Price="16000" OnSale="N" Account="JOHNH" />
</Region>
<Region id="3"></Region>
<Region id="4"></Region>
</Vendor>
</Geography>
</Response>
This is my Program.cs:
namespace XMLDeserializeExample
{
class Program
{
static void Main(string[] args)
{
string path = #"c:\XMLFile1.xml";
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "Response";
XmlSerializer ser = new XmlSerializer(typeof(ResponseGeographyVendorRegionVehicle), xRoot);
ResponseGeographyVendorRegionVehicle i;
using (Stream reader = new FileStream(path,FileMode.Open))
{
i = (ResponseGeographyVendorRegionVehicle)ser.Deserialize(reader);
Console.WriteLine(i.Price);
Console.ReadLine();
}
}
}
}
This is the Paste Special Response.CS file that was created:
namespace XMLDeserializeExample
{
}
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Response
{
private ResponseGeography geographyField;
/// <remarks/>
public ResponseGeography Geography
{
get
{
return this.geographyField;
}
set
{
this.geographyField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseGeography
{
private ResponseGeographyVendor vendorField;
/// <remarks/>
public ResponseGeographyVendor Vendor
{
get
{
return this.vendorField;
}
set
{
this.vendorField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseGeographyVendor
{
private ResponseGeographyVendorRegion[] regionField;
private string idField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Region")]
public ResponseGeographyVendorRegion[] Region
{
get
{
return this.regionField;
}
set
{
this.regionField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string id
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseGeographyVendorRegion
{
private ResponseGeographyVendorRegionVehicle[] vehicleField;
private byte idField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Vehicle")]
public ResponseGeographyVendorRegionVehicle[] Vehicle
{
get
{
return this.vehicleField;
}
set
{
this.vehicleField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte id
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ResponseGeographyVendorRegionVehicle
{
private string makeField;
private string fuelField;
private ushort priceField;
private string onSaleField;
private string accountField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Make
{
get
{
return this.makeField;
}
set
{
this.makeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Fuel
{
get
{
return this.fuelField;
}
set
{
this.fuelField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public ushort Price
{
get
{
return this.priceField;
}
set
{
this.priceField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string OnSale
{
get
{
return this.onSaleField;
}
set
{
this.onSaleField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Account
{
get
{
return this.accountField;
}
set
{
this.accountField = value;
}
}
}
Please let me know how I can better explain myself. Apologies if none of this makes sense- welcome to my weekend lol.
Thank you.
As your xml-root is obviously a Response instead of a ResponseGeographyVendor you have to de-serialize to that type:
string path = #"c:\XMLFile1.xml";
XmlSerializer ser = new XmlSerializer(typeof(response);
ResponseGeographyVendor i;
using (Stream reader = new FileStream(path,FileMode.Open))
{
i = ((Response)ser.Deserialize(reader)).Geography.Vendor;
Console.WriteLine(i.Price);
Console.ReadLine();
}
A serializer will only work on the entire xml-document. You can´t just write or read parts of it. So just use the xml, serialize it to an instance of Response and get its Geography-member.
Now you can easily get the 3rd Vehicle within the second Region:
var vehicle = i.Region[1].Vehicle[2];
Notice that you don´t need to provide the xml-root yourself.
You'll want to use the XML Serializer that's built into .Net.
First create a class to represent the XML document data:
public class Response
{
public Geography Geography {get; set;}
}
public class Geography
{
public Vendor Vendor{get;set;}
}
public class Vendor
{
public List<Region> Regions {get;set;}
}
public class Region
{
}
and so on.
Then read the xml as a string and deserialize it:
string myXml = File.ReadAsStringAsync(filepath).Result;
XmlSerializer ser = new XmlSerializer(typeof(Response));
using (TextReader reader = new StringReader(myXml)
{
Response myResponse = ser.Deserialize(reader);
}
Then you can iterate through all the properties and stuff on the Geography object.
I have to interact with a repository of documents, where each document is inserted with metadata contained in an XML document.
Now, at some point, this metadata must be generated from scratch. I thought that using a class to create this XML will be the best solution.
I generate the class using the Developer Command Prompt, this is the result:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://example.com/metadata")]
[System.Xml.Serialization.XmlRootAttribute(ElementName = "Metadata", Namespace="http://example.com/metadata", IsNullable=false)]
public partial class XmlMetadata {
private System.Xml.XmlElement[] anyField;
[System.Xml.Serialization.XmlAnyElementAttribute()]
public System.Xml.XmlElement[] Any {
get {
return this.anyField;
}
set {
this.anyField = value;
}
}
}
This class shoud be able to generate XML documents like this:
<?xml version="1.0" encoding="utf-8"?>
<md:Metadata xmlns:md="http://example.com/metadata">
<md:Cert>0001</md:Cert>
<md:Model>Test</md:Model>
<md:Created>2015-05-21</md:Created>
</md:Metadata>
QUESTION 1: Is this class enough descriptive to generate this kind of XML documents? (Note the prefix on every tag and how every tag have a different name, also I must be able to insert any number of elements)
QUESTION 2: How I insert elements in an instance of this class? This elements have the form of a KeyValuePair, where the key represent the tag name.
QUESTION 3: How do I serialize this class into a stream and into a Base64 string from there?
Thanks in advance
I would do it like this
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)
{
XmlMetadata data = new XmlMetadata(){
elemements = new List<Element>(){
new Element(){ name = "cert", value = "0001"},
new Element(){ name = "model", value = "Test"},
new Element(){ name = "created", value = "2015-05-21"}
}
};
XmlSerializer serializer = new XmlSerializer(typeof(XmlMetadata));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("md", "http://example.com/metadata");
StreamWriter writer = new StreamWriter(FILENAME);
serializer.Serialize(writer, data, ns);
writer.Flush();
writer.Close();
writer.Dispose();
XmlSerializer xs = new XmlSerializer(typeof(XmlMetadata));
XmlTextReader reader = new XmlTextReader(FILENAME);
XmlMetadata newData = (XmlMetadata)xs.Deserialize(reader);
}
}
[XmlRootAttribute(ElementName = "Metadata", Namespace = "http://example.com/metadata", IsNullable = false)]
public class XmlMetadata
{
[XmlElement(ElementName = "Element", Namespace = "http://example.com/metadata", IsNullable = false)]
public List<Element> elemements { get; set; }
}
[XmlRootAttribute(ElementName = "Element", Namespace = "http://example.com/metadata", IsNullable = false)]
public class Element
{
[XmlAttribute(AttributeName = "name",Namespace = "http://example.com/metadata")]
public string name {get; set; }
[XmlAttribute(AttributeName = "value", Namespace = "http://example.com/metadata")]
public string value { get; set; }
}
}
Try this
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)
{
XmlMetadata data = new XmlMetadata()
{
cert = "0001",
model = "Test",
created = DateTime.Parse("2015-05-21")
};
XmlSerializer serializer = new XmlSerializer(typeof(XmlMetadata));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("md", "http://example.com/metadata");
StreamWriter writer = new StreamWriter(FILENAME);
serializer.Serialize(writer, data, ns);
writer.Flush();
writer.Close();
writer.Dispose();
XmlSerializer xs = new XmlSerializer(typeof(XmlMetadata));
XmlTextReader reader = new XmlTextReader(FILENAME);
XmlMetadata newData = (XmlMetadata)xs.Deserialize(reader);
}
}
[XmlRootAttribute(ElementName = "Metadata", Namespace = "http://example.com/metadata", IsNullable = false)]
public class XmlMetadata
{
[XmlElement(ElementName = "Cert", Namespace = "http://example.com/metadata", IsNullable = false)]
public string cert {get;set;}
[XmlElement(ElementName = "Model", Namespace = "http://example.com/metadata", IsNullable = false)]
public string model {get;set;}
[XmlElement(ElementName = "Created", Namespace = "http://example.com/metadata", IsNullable = false)]
public DateTime created {get;set;}
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I need to generate this xml from a c# code however i m lost in xmlwriter provided multiple writers.. Can anyone who got expertise in xml can help me out for writing C# code to produce this below xml:
<?xml version="1.0" encoding="utf-16" ?>
<Request xmlns="http://www.ABC.com/submit" xmlns:l="http://www.ABC.com/link" l:source="SRC" l:date="2014-03-05">
<MyData l:identifier="PRAV" l:value="151.19448366182007269092408546">
<DATA1 l:value="0.151328110447635" />
<DATA2 l:value="0.6461191930062688087600920641" />
<DATA3 l:value="0.144793773777417" />
</MyData>
</Request>
Use the Paste Special feature of Visual Studio.
With this you can copy your XML structure (provided it is valid which currently it isn't).
Select:
Edit
Paste Special
Paste XML as Classes
This will give you a class representing your XML:
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.ABC.com/submit")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.ABC.com/submit", IsNullable = false)]
public partial class Request
{
private RequestMyData myDataField;
private string sourceField;
private System.DateTime dateField;
/// <remarks/>
public RequestMyData MyData
{
get
{
return this.myDataField;
}
set
{
this.myDataField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.ABC.com/link")]
public string source
{
get
{
return this.sourceField;
}
set
{
this.sourceField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.ABC.com/link", DataType = "date")]
public System.DateTime date
{
get
{
return this.dateField;
}
set
{
this.dateField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.ABC.com/submit")]
public partial class RequestMyData
{
private RequestMyDataDATA1 dATA1Field;
private RequestMyDataDATA2 dATA2Field;
private RequestMyDataDATA3 dATA3Field;
private string identifierField;
private decimal valueField;
/// <remarks/>
public RequestMyDataDATA1 DATA1
{
get
{
return this.dATA1Field;
}
set
{
this.dATA1Field = value;
}
}
/// <remarks/>
public RequestMyDataDATA2 DATA2
{
get
{
return this.dATA2Field;
}
set
{
this.dATA2Field = value;
}
}
/// <remarks/>
public RequestMyDataDATA3 DATA3
{
get
{
return this.dATA3Field;
}
set
{
this.dATA3Field = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.ABC.com/link")]
public string identifier
{
get
{
return this.identifierField;
}
set
{
this.identifierField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.ABC.com/link")]
public decimal value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.ABC.com/submit")]
public partial class RequestMyDataDATA1
{
private decimal valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.ABC.com/link")]
public decimal value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.ABC.com/submit")]
public partial class RequestMyDataDATA2
{
private decimal valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.ABC.com/link")]
public decimal value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.ABC.com/submit")]
public partial class RequestMyDataDATA3
{
private decimal valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.ABC.com/link")]
public decimal value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
If you write your classes as DataContracts and assigns XML attributes to the DataMembers you should be able to get what you need.
[DataContract]
public class Request
{
[DataMember, XmlAttribute]
public string Source { get; set; }
[DataMember]
public MyData MyData { get; set; }
}
[DataContract]
public class MyData
{
[DataMember, XmlAttribute]
public string Identifier { get; set; }
[DataMember, XmlAttribute]
public double Value { get; set; }
[DataMember]
public List<Data> Datum { get; set; }
}
[DataContract]
public class Data
{
[DataMember, XmlAttribute]
public double Value { get; set; }
}
and to test
var listOfData = new List<Data> {new Data {Value = 0.15}, new Data {Value = 0.64}};
var myData = new MyData {Identifier = "PRAV", Value = 151.194, Datum = listOfData};
var request = new Request {MyData = myData, Source = "SRC"};
XmlSerializer ser = new XmlSerializer(typeof(Request));
StringWriter sw = new StringWriter();
ser.Serialize(sw, request);
Console.WriteLine(sw.ToString());
Thiis will result in
<?xml version="1.0" encoding="utf-16"?>
<Request
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http:/ /www.w3.org/2001/XMLSchema" Source="SRC">
<MyData Identifier="PRAV" Value="151.194">
<Datum>
<Data Value="0.15" />
<Data Value="0.64" />
</Datum>
</MyData>
</Request>
You can use XDocument to create XML file from C# :
using System.Xml.Linq;
var doc = new XDocument(new XDeclaration("1.0", "utf-16", ""));
XNamespace ns = "http://www.ABC.com/submit";
XNamespace l = "http://www.ABC.com/link";
//<Request>
doc.Add(new XElement(ns+"Request",
//xmlns="http://www.ABC.com/submit"
new XAttribute("xmlns", "http://www.ABC.com/submit"),
//xmlns:l="http://www.ABC.com/link"
new XAttribute(XNamespace.Xmlns + "l", "http://www.ABC.com/link"),
//l:source="SRC"
new XAttribute(l+"source", "SRC"),
//l:date="2014-03-05"
new XAttribute(l + "date", "2014-03-05"),
//<MyData>
new XElement(ns+"MyData",
//l:identifier="PRAV"
new XAttribute(l+"identifier", "PRAV"),
//l:value="151.19448366182007269092408546"
new XAttribute(l + "value", "151.19448366182007269092408546"),
//<DATA1>
new XElement(ns+"DATA1",
//l:value="0.151328110447635"
new XAttribute(l + "value", "0.151328110447635")),
//<DATA2>
new XElement(ns+"DATA2",
//l:value="0.6461191930062688087600920641"
new XAttribute(l + "value", "0.6461191930062688087600920641")),
//<DATA3>
new XElement(ns+"DATA3",
//l:value="0.144793773777417"
new XAttribute(l + "value", "0.144793773777417")))));
doc.Save("xml_name.xml");