Using Linq to parse XML data into an object in c# - c#

I have a fairly messy XML structure that I need to process and display to the end user. The XML structure holds information about Bars of metal and the Cuts to be made for each bar. The goal is to process this file, display to the user a list of the bars grouped by bar type. They can select a bar from this list where a gridview of some sort will display the cuts for that bar. They can then select a cut and the label information for that cut will be used to create a label with a barcode and some other information.
The structure of the XML can be seen below:
<BODY>
<BAR>
<BRAN>ALSPEC</BRAN>
<SYST>Hunter 100mm Flush Glazed</SYST>
<CODE>AS308</CODE>
<DESC>Door Adaptor</DESC>
<DICL>NOTRE DAME GLOSS</DICL>
<DOCL>notre dame gloss p/coat</DOCL>
<LEN> 6500</LEN>
<STS>1</STS>
<POS> 0</POS>
<SVL> 0</SVL>
<IVL> 0</IVL>
<VROT> 0</VROT>
<VU1S> 0</VU1S>
<VU1D> 0</VU1D>
<VU2S> 0</VU2S>
<VU2D> 0</VU2D>
<LENR> 201.3</LENR>
<H> 26.5</H>
<MLT> 1</MLT>
<SCP> 0</SCP>
<BRS> 0</BRS>
<IFS> 0</IFS>
<BS1L> 0</BS1L>
<BS1R> 0</BS1R>
<BS2L> 0</BS2L>
<BS2R> 0</BS2R>
<ENTH> 0</ENTH>
<CUT>
<NUM> 1</NUM>
<TYPE></TYPE>
<ANGL> 45</ANGL>
<ANGR> 90</ANGR>
<AB1> 90</AB1>
<AB2> 90</AB2>
<IL> 2064</IL>
<OL> 2090.5</OL>
<BCOD>000000231/5/44</BCOD>
<CSNA></CSNA>
<CSNU></CSNU>
<TINA></TINA>
<DESC>Jamb - Right</DESC>
<STAT> 1</STAT>
<LBL>Job# 760 Item# 5</LBL>
<LBL>2090.5 mm</LBL>
<LBL>W2-D8/T15</LBL>
<LBL>Jamb - Right</LBL>
</CUT>
<CUT>
<NUM> 1</NUM>
<TYPE></TYPE>
<ANGL> 45</ANGL>
<ANGR> 90</ANGR>
<AB1> 90</AB1>
<AB2> 90</AB2>
<IL> 2064</IL>
<OL> 2090.5</OL>
<BCOD>000000231/2/45</BCOD>
<CSNA></CSNA>
<CSNU></CSNU>
<TINA></TINA>
<DESC>Jamb - Right</DESC>
<STAT> 1</STAT>
<LBL>Job# 760 Item# 2</LBL>
<LBL>2090.5 mm</LBL>
<LBL>D8/T23</LBL>
<LBL>Jamb - Right</LBL>
</CUT>
<CUT>
<NUM> 1</NUM>
<TYPE></TYPE>
<ANGL> 90</ANGL>
<ANGR> 45</ANGR>
<AB1> 90</AB1>
<AB2> 90</AB2>
<IL> 2064</IL>
<OL> 2090.5</OL>
<BCOD>000000231/1/43</BCOD>
<CSNA></CSNA>
<CSNU></CSNU>
<TINA></TINA>
<DESC>Jamb - Left</DESC>
<STAT> 1</STAT>
<LBL>Job# 760 Item# 1</LBL>
<LBL>2090.5 mm</LBL>
<LBL>D8/T24</LBL>
<LBL>Jamb - Left</LBL>
</CUT>
</BAR>
</BODY>
The result I am looking for is something like below i.e a tree view on the left and a datagridview on the right displaying all the cuts in the job, filtered by the tree view selection (only cuts from the selected tree view level down).
GUI Layout
To achieve this I am trying to use LINQ to XML to parse the XML file into a class i have created:
public List<Bars> bars = new List<Bars>();
public class Bars
{
public int Bar_id { set; get; }
public string Brand { set; get; }
public string System { set; get; }
public string Code { set; get; }
public string Description { set; get; }
public string Length { set; get; }
public string Status { set; get; }
public string NumBars { set; get; }
public List<Cuts> Cuts { set; get; }
}
public class Cuts
{
public int Cut_id { set; get; }
public int Bar_id { set; get; }
public string AngleL { set; get; }
public string AngleR { set; get; }
public string LenInn { set; get; }
public string LenOut { set; get; }
public string Barcode { set; get; }
public string Description { set; get; }
public string Status { set; get; }
public string Label1 { set; get; }
public string Label2 { set; get; }
public string Label3 { set; get; }
public string Label4 { set; get; }
}
I'm actually looking for some advise on weather or not this is the correct way to handle this kind of project (LINQ to XML). Should I be using data sets or some other form or data storage.
I am new to XML and also to relational database type stuff so any advice will be greatly appreciated. Thanks in advance!
Will

Given a choice, Iwould thoroughly recommend using XDocument(LINQ to XML). It's much simpler to create documents and process them. Personally, my preferred choice in dealing large Xml.
var result = doc.Descendants("BAR")
.Select((e, i)=> new Bars()
{
Bar_id = i +1,
Brand = e.Element("BRAN").Value,
System = e.Element("SYST").Value,
Code = e.Element("CODE").Value,
Description = e.Element("DESC").Value,
Length =e.Element("LEN").Value,
Status =e.Element("STS").Value,
// remaining fileds
Cuts = e.Descendants("CUT").Select(c=> new Cuts()
{
Cut_id = int.Parse(c.Element("NUM").Value),
Bar_id = i+1,
AngleL = c.Element("ANGL").Value,
AngleR = c.Element("ANGR").Value,
LenInn = c.Element("IL").Value,
LenOut = c.Element("OL").Value,
Barcode = c.Element("BCOD").Value,
Description = c.Element("DESC").Value,
Status = c.Element("STAT").Value,
Label1 = c.Elements("LBL").First().Value,
Label2 = c.Elements("LBL").Skip(1).First().Value,
Label3 = c.Elements("LBL").Skip(2).First().Value,
Label4 = c.Elements("LBL").Skip(3).First().Value,
}).ToList(),
}).ToList();
Working Demo

Since you wanted some suggestion here is an easy way of doing it. When it comes to this kind of situations, serialisation is the easiest option. VS has inbuilt functionality to code generate classes for this kind of xml structures.
You can use Edit > Paste Special feature for this purpose. So your classes will look like;
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class BODY
{
private BODYBAR bARField;
/// <remarks/>
public BODYBAR BAR
{
get
{
return this.bARField;
}
set
{
this.bARField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class BODYBAR
{
private string bRANField;
private string sYSTField;
private string cODEField;
private string dESCField;
private string dICLField;
private string dOCLField;
private ushort lENField;
private byte sTSField;
private byte pOSField;
private byte sVLField;
private byte iVLField;
private byte vROTField;
private byte vU1SField;
private byte vU1DField;
private byte vU2SField;
private byte vU2DField;
private decimal lENRField;
private decimal hField;
private byte mLTField;
private byte sCPField;
private byte bRSField;
private byte iFSField;
private byte bS1LField;
private byte bS1RField;
private byte bS2LField;
private byte bS2RField;
private byte eNTHField;
private BODYBARCUT[] cUTField;
/// <remarks/>
public string BRAN
{
get
{
return this.bRANField;
}
set
{
this.bRANField = value;
}
}
/// <remarks/>
public string SYST
{
get
{
return this.sYSTField;
}
set
{
this.sYSTField = value;
}
}
/// <remarks/>
public string CODE
{
get
{
return this.cODEField;
}
set
{
this.cODEField = value;
}
}
/// <remarks/>
public string DESC
{
get
{
return this.dESCField;
}
set
{
this.dESCField = value;
}
}
/// <remarks/>
public string DICL
{
get
{
return this.dICLField;
}
set
{
this.dICLField = value;
}
}
/// <remarks/>
public string DOCL
{
get
{
return this.dOCLField;
}
set
{
this.dOCLField = value;
}
}
/// <remarks/>
public ushort LEN
{
get
{
return this.lENField;
}
set
{
this.lENField = value;
}
}
/// <remarks/>
public byte STS
{
get
{
return this.sTSField;
}
set
{
this.sTSField = value;
}
}
/// <remarks/>
public byte POS
{
get
{
return this.pOSField;
}
set
{
this.pOSField = value;
}
}
/// <remarks/>
public byte SVL
{
get
{
return this.sVLField;
}
set
{
this.sVLField = value;
}
}
/// <remarks/>
public byte IVL
{
get
{
return this.iVLField;
}
set
{
this.iVLField = value;
}
}
/// <remarks/>
public byte VROT
{
get
{
return this.vROTField;
}
set
{
this.vROTField = value;
}
}
/// <remarks/>
public byte VU1S
{
get
{
return this.vU1SField;
}
set
{
this.vU1SField = value;
}
}
/// <remarks/>
public byte VU1D
{
get
{
return this.vU1DField;
}
set
{
this.vU1DField = value;
}
}
/// <remarks/>
public byte VU2S
{
get
{
return this.vU2SField;
}
set
{
this.vU2SField = value;
}
}
/// <remarks/>
public byte VU2D
{
get
{
return this.vU2DField;
}
set
{
this.vU2DField = value;
}
}
/// <remarks/>
public decimal LENR
{
get
{
return this.lENRField;
}
set
{
this.lENRField = value;
}
}
/// <remarks/>
public decimal H
{
get
{
return this.hField;
}
set
{
this.hField = value;
}
}
/// <remarks/>
public byte MLT
{
get
{
return this.mLTField;
}
set
{
this.mLTField = value;
}
}
/// <remarks/>
public byte SCP
{
get
{
return this.sCPField;
}
set
{
this.sCPField = value;
}
}
/// <remarks/>
public byte BRS
{
get
{
return this.bRSField;
}
set
{
this.bRSField = value;
}
}
/// <remarks/>
public byte IFS
{
get
{
return this.iFSField;
}
set
{
this.iFSField = value;
}
}
/// <remarks/>
public byte BS1L
{
get
{
return this.bS1LField;
}
set
{
this.bS1LField = value;
}
}
/// <remarks/>
public byte BS1R
{
get
{
return this.bS1RField;
}
set
{
this.bS1RField = value;
}
}
/// <remarks/>
public byte BS2L
{
get
{
return this.bS2LField;
}
set
{
this.bS2LField = value;
}
}
/// <remarks/>
public byte BS2R
{
get
{
return this.bS2RField;
}
set
{
this.bS2RField = value;
}
}
/// <remarks/>
public byte ENTH
{
get
{
return this.eNTHField;
}
set
{
this.eNTHField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("CUT")]
public BODYBARCUT[] CUT
{
get
{
return this.cUTField;
}
set
{
this.cUTField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class BODYBARCUT
{
private byte nUMField;
private object tYPEField;
private byte aNGLField;
private byte aNGRField;
private byte aB1Field;
private byte aB2Field;
private ushort ilField;
private decimal olField;
private string bCODField;
private object cSNAField;
private object cSNUField;
private object tINAField;
private string dESCField;
private byte sTATField;
private string[] lBLField;
/// <remarks/>
public byte NUM
{
get
{
return this.nUMField;
}
set
{
this.nUMField = value;
}
}
/// <remarks/>
public object TYPE
{
get
{
return this.tYPEField;
}
set
{
this.tYPEField = value;
}
}
/// <remarks/>
public byte ANGL
{
get
{
return this.aNGLField;
}
set
{
this.aNGLField = value;
}
}
/// <remarks/>
public byte ANGR
{
get
{
return this.aNGRField;
}
set
{
this.aNGRField = value;
}
}
/// <remarks/>
public byte AB1
{
get
{
return this.aB1Field;
}
set
{
this.aB1Field = value;
}
}
/// <remarks/>
public byte AB2
{
get
{
return this.aB2Field;
}
set
{
this.aB2Field = value;
}
}
/// <remarks/>
public ushort IL
{
get
{
return this.ilField;
}
set
{
this.ilField = value;
}
}
/// <remarks/>
public decimal OL
{
get
{
return this.olField;
}
set
{
this.olField = value;
}
}
/// <remarks/>
public string BCOD
{
get
{
return this.bCODField;
}
set
{
this.bCODField = value;
}
}
/// <remarks/>
public object CSNA
{
get
{
return this.cSNAField;
}
set
{
this.cSNAField = value;
}
}
/// <remarks/>
public object CSNU
{
get
{
return this.cSNUField;
}
set
{
this.cSNUField = value;
}
}
/// <remarks/>
public object TINA
{
get
{
return this.tINAField;
}
set
{
this.tINAField = value;
}
}
/// <remarks/>
public string DESC
{
get
{
return this.dESCField;
}
set
{
this.dESCField = value;
}
}
/// <remarks/>
public byte STAT
{
get
{
return this.sTATField;
}
set
{
this.sTATField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("LBL")]
public string[] LBL
{
get
{
return this.lBLField;
}
set
{
this.lBLField = value;
}
}
}
Then you can simply deserialise;
BODY objBody = new BODY();
var xml = File.ReadAllText(#"C:\XMLFile2.xml");
using (var reader = new StringReader(xml))
{
var serialiser = new XmlSerializer(typeof(BODY));
objBody = (BODY)serialiser.Deserialize(reader);
}

Related

C# GroupBy is returning multiple elements, even when the objects compared in the group by clause are identical

I have a list of a complex object with some list of objects. At the third level of the object, I have a property called ProductServiceKey. I need to get a new list of objects, in order to get those ProductServicesKeys grouped by if the dictionary called FeatureList contains the same values. Here are my object structures. I will only paste the relevant class info for this question:
Orders:
public class Orders : IValidatableObject
{
#region Constants
#endregion
#region Fields
List<Order> _orderList;
#endregion
#region Events
#endregion
#region Properties
/// <summary>
/// Gets or sets the List of Order
/// </summary>
/// <value></value>
public List<Order> OrderListD
{
get { return this._orderList; }
set { this._orderList = value; }
}
}
OrderListD that is of type Order:
public class Order : IValidatableObject
{
#region Constants
#endregion
public enum OrderStatus { OrderPending, OrderSubmitted, OrderProcessed, OrderFailed, OrderNoResponse}
public enum OrderCompletionStatus { ProductServiceUpdateFailed, ProductServiceUpdateSuccess, FeatureUpdateFailed, FeatureUpdateSuccess }
#region Fields
private int _orderID;
private Guid _orderGuid;
private System.Nullable<DateTime> _submittedOn;
private System.Nullable<DateTime> _lastUpdatedOn;
private List<ProductService> _services;
private OrderStatus _status;
private string _orderType;
private string _errorCode = string.Empty;
private string _errorDesc = string.Empty;
#endregion
#region Events
#endregion
#region Properties
public Guid OrderGuid
{
get
{
return _orderGuid;
}
set { this._orderGuid = value; }
}
public OrderStatus Status
{
get { return this._status; }
set { this._status = value; }
}
public string Type
{
get { return this._orderType; }
set { this._orderType = value; }
}
public string ErrorCode
{
get { return this._errorCode; }
set { this._errorCode = value; }
}
public string ErrorDescription
{
get { return this._errorDesc; }
set { this._errorDesc = value; }
}
/// <summary>
/// Gets or sets the OrderID
/// </summary>
/// <value></value>
public int OrderId
{
get { return this._orderID; }
set { this._orderID = value; }
}
/// <summary>
/// Submitted Date
/// </summary>
public System.Nullable<DateTime> SubmittedOn
{
get { return this._submittedOn; }
set { this._submittedOn = value; }
}
/// <summary>
/// LastUpdated Date
/// </summary>
public System.Nullable<DateTime> LastUpdatedOn
{
get { return this._lastUpdatedOn; }
set { this._lastUpdatedOn = value; }
}
/// <summary>
///Product Services associated with the Order
/// </summary>
public List<ProductService> Services
{
get { return this._services; }
set { this._services = value; }
}
public string GroupId { get; set; }
}
Services, that is a list of type ProductService:
public class ProductService : ICloneable, IValidatableObject
{
#region Constants
public const string PhoneType = "DPHONE";
public const string VoicemailType = "VMAIL";
public const string HuntGroupType = "HGROUP";
public const string BusinessGroupType = "BGROUP";
public const string AutoAttendantType = "AA";
public const string AccountCodesType = "AUTH";
#endregion
#region Fields
private string _autoAttendantID;
private string _aaEditmemberID;
private string _subscriberID;
private string _accountDeviceID;
private string _productServiceID;
private string _productServiceKey;
private string _productServiceCode;
private string _productServiceName;
private string _productServiceType;
private string _productServiceStatus;
private string _primaryProvider;
private string _lastUpdatedOn;
private Order.OrderCompletionStatus _productServiceOrderStatus;
private Offer _offerRef;
private Dictionary<string, Feature> _featureList = new Dictionary<string, Feature>(StringComparer.InvariantCultureIgnoreCase);
private Schedule _schedule;
private List<Profile> _profiles;
//private Dictionary<string, Mailbox> _mailboxList;
private List<ProductServiceAttribute<string, string>> _productServiceAttributeList;
private string _action;
private TWC.FeatureSet.Order.OrderStatus _status;
private string _BPSErrorMessage = string.Empty;
#endregion
#region Events
#endregion
#region Properties
public Order.OrderCompletionStatus ProductServiceOrderStatus
{
get { return this._productServiceOrderStatus; }
set { this._productServiceOrderStatus = value; }
}
public Schedule Schedule
{
get { return _schedule; }
set { _schedule = value; }
}
public List<Profile> Profiles
{
get { return _profiles; }
set { _profiles = value; }
}
/// <summary>
/// Gets or sets the MailboxList
/// </summary>
/// <value></value>
//public Dictionary<string, Mailbox> MailboxList
//{
// get { return this._mailboxList; }
// set { this._mailboxList = value; }
//}
/// <summary>
/// Gets or sets the ProductServiceID
/// </summary>
/// <value></value>
public string ProductServiceId
{
get { return this._productServiceID; }
set { this._productServiceID = value; }
}
public string ProductServiceAction
{
get { return this._action; }
set { this._action = value; }
}
public string ProductServiceStatus
{
get { return this._productServiceStatus; }
set { this._productServiceStatus = value; }
}
public string ProductServiceKey
{
get { return this._productServiceKey; }
set { this._productServiceKey = value; }
}
/// <summary>
/// Gets or sets the PoductServiceCode
/// </summary>
/// <value></value>
public string ProductServiceCode
{
get { return this._productServiceCode; }
set { this._productServiceCode = value; }
}
// <summary>
/// Gets or sets the SubScriiberID
/// </summary>
/// <value></value>
public string SubscriberId
{
get { return this._subscriberID; }
set { this._subscriberID = value; }
}
public string AccountDeviceId
{
get { return this._accountDeviceID; }
set { this._accountDeviceID = value; }
}
public string AutoAttendantId
{
get { return this._autoAttendantID; }
set { this._autoAttendantID = value; }
}
public string AAEditmemberId
{
get { return this._aaEditmemberID; }
set { this._aaEditmemberID = value; }
}
/// <summary>
/// Gets or sets the ProductServiceName
/// </summary>
/// <value></value>
public string ProductServiceName
{
get { return this._productServiceName; }
set { this._productServiceName = value; }
}
/// <summary>
/// Gets or sets the ProductServiceType
/// </summary>
/// <value></value>
public string ProductServiceType
{
get { return this._productServiceType; }
set { this._productServiceType = value; }
}
/// <summary>
/// Gets or sets the PrimaryProvider
/// </summary>
/// <value></value>
public string PrimaryProvider
{
get { return this._primaryProvider; }
set { this._primaryProvider = value; }
}
/// <summary>
/// Gets or sets the lastupdated on
/// </summary>
public string LastUpdatedOn
{
get { return this._lastUpdatedOn; }
set { this._lastUpdatedOn = value; }
}
/// <summary>
///Offer associated with the Product service
/// </summary>
public Offer OfferRef
{
get { return this._offerRef; }
set { this._offerRef = value; }
}
/// <summary>
///Product Service Attribute associated with the Product service
/// </summary>
public List<ProductServiceAttribute<string, string>> ProductServiceAttributeList
{
get { return this._productServiceAttributeList; }
set { this._productServiceAttributeList = value; }
}
/// <summary>
///Feature List associated with the Product service
/// </summary>
public Dictionary<string, Feature> FeatureList
{
get { return this._featureList; }
set { this._featureList = value; }
}
public TWC.FeatureSet.Order.OrderStatus OrderStatusForService
{
get { return this._status; }
set { this._status = value; }
}
public string BPSErrorMessage
{
get { return this._BPSErrorMessage; }
set { this._BPSErrorMessage = value; }
}
public string Action { get; set; }
#endregion
}
And so, when I try to group by FeatureList, I use this line of code:
var groupedOrderList = orders.OrderListD.GroupBy(u => u.Services[0].FeatureList).Select(grp => grp.First()).ToList();
My problem is that the new list called groupedOrderList created by the GroupBy, in my debugging session, has two elements instead of one. In my debuggin, FeatureList values are similar.
I also tried using the values property from the dictionary, as shown:
var groupedOrderList = orders.OrderListD.GroupBy(u => u.Services[0].FeatureList.Values).Select(grp => grp.First()).ToList();
This is driving me crazy. Why I'm not getting it grouped properly??? I should only have one element in the list, because in the 2 elements in the original list (OrderListD), it's FeatureList dictionary has the same values!!
Any help?
Thank you!

List<Model> comes back as Null

new to ASP.net and have a question involving a model that has multiple variables of the same type.
I have Order model that can have 0 to n Detail models attached to it. When I POST the http request I get all the information for the Order except the Detail model always comes back as null. Or more specifically the ".count" method on the List is 0.
How can I get it to post all the Details for my Model?
Order Model:
public struct shipTo
{
public string id;
public string Line1;
public int PostalCode;
public string City;
public string State;
public string CountryCode;
}
namespace USS_EDIv2.Models
{
public class Order
{
public Int64 SalesOrderNumber { get; set; }
public Int64 PurchaseOrderNumber { get; set; }
public Int64 BranchPlant { get; set; }
public shipTo ShipTo;
public Int64 Quantity { get; set; }
public string UOM { get; set; }
public List<Detail> Detail = new List<Detail>();
}
}
Detail Model:
namespace USS_EDIv2.Models
{
public class Detail
{
public string LineNumber;
public string GradeItem;
public string Quantity;
public string UOM;
public string RequestDate;
public string Status;
public Detail()
{
LineNumber = "1";
GradeItem = "1";
Quantity = "1";
UOM = "1";
RequestDate = "1";
Status = "1";
}
}
}
Repository class:
namespace USS_EDIv2.Services
{
public class SalesRepository
{
public DateTime currentTime = System.DateTime.Now;
private const string CacheKey = "4041tmtTEST1337";
public string xml;
public int i;
public Order[] GetAllSales()
{
var ctx = HttpContext.Current;
if (ctx != null)
{
return (Order[])ctx.Cache[CacheKey];
}
return new Order[]
{
new Order
{
}
};
}
public SalesRepository()
{
var ctx = HttpContext.Current;
if (ctx != null)
{
if (ctx.Cache[CacheKey] == null)
{
var sales = new Order[]
{
};
{
};
ctx.Cache[CacheKey] = sales;
//ctx.Cache.Remove("4041tmtTEST1337");
}
}
}
public bool SaveSale(Order sales)
{
var ctx = HttpContext.Current;
if (ctx != null)
{
try
{
var currentData = ((Order[])ctx.Cache[CacheKey]).ToList();
currentData.Add(sales);
ctx.Cache[CacheKey] = currentData.ToArray();
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return false;
}
}
return false;
}
}
}
And my Controller:
namespace USS_EDIv2.Controllers
{
public class NewOrderController : ApiController
{
public DateTime currentTime = System.DateTime.Now;
private SalesRepository salesRepository;
public int i;
public NewOrderController()
{
this.salesRepository = new SalesRepository();
}
public Order[] Get()
{
return salesRepository.GetAllSales();
}
public HttpResponseMessage Post(Order sale)
{
var ctx = HttpContext.Current;
this.salesRepository.SaveSale(sale);
var response = Request.CreateResponse<Order> (System.Net.HttpStatusCode.Created, sale);
return response;
}
}
}
This is the XML data being requested:
<Order>
<SalesOrderNumber>1294288</SalesOrderNumber>
<PurchaseOrderNumber>81896</PurchaseOrderNumber>
<BranchPlant>9701</BranchPlant>
<ShipTo id="string">
<Line1>RAIL TRACK #769 SPOT 00</Line1>
<PostalCode>79765</PostalCode>
<City>MIDLAND COUNTY</City>
<State>TX</State>
<CountryCode>US</CountryCode>
</ShipTo>
<Quantity>75</Quantity>
<UOM>TN</UOM>
<Detail created="2015-12-14T13:59:57.84" action="Create">
<LineNumber>1.0</LineNumber>
<GradeItem>97010B00000</GradeItem>
<Quantity>25.000</Quantity>
<UOM>TN</UOM>
<RequestDate>2015-07-11</RequestDate>
<Status>Open</Status>
</Detail>
<Detail created="2015-12-14T13:59:57.84" action="Create">
<LineNumber>2.0</LineNumber>
<GradeItem>97010B00000</GradeItem>
<Quantity>25</Quantity>
<UOM>TN</UOM>
<RequestDate>2002-02-07</RequestDate>
<Status>Open</Status>
</Detail>
<Detail created="2015-05-22T02:29:50.78" action="Create">
<LineNumber>3.0</LineNumber>
<GradeItem>97010B00000</GradeItem>
<Quantity>25</Quantity>
<UOM>TN</UOM>
<RequestDate>2015-07-11</RequestDate>
<Status>Open</Status>
</Detail>
</Order>
And this is my current response:
<ArrayOfOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Order>
<ShipTo>
<Line1>RAIL TRACK #769 SPOT 00</Line1>
<PostalCode>79765</PostalCode>
<City>MIDLAND COUNTY</City>
<State>TX</State>
<CountryCode>US</CountryCode>
</ShipTo>
************HERE LIES THE PROBLEM
<Detail/>
************
<SalesOrderNumber>1294288</SalesOrderNumber>
<PurchaseOrderNumber>81896</PurchaseOrderNumber>
<BranchPlant>9701</BranchPlant>
<Quantity>75</Quantity>
<UOM>TN</UOM>
</Order>
</ArrayOfOrder>
I also have no control over changing the format of the incoming xml data. Any pointer in the right direction would be helpful please.
Debug:
[debug] (http://imgur.com/RVnpZ0S)
Okay,
So I solved this by copying the XML data onto my clipboard, creating a new class and then going to Edit -> Paste Special -> Paste XML as classes
and it came up with this:
namespace USS_EDIv2.Models
{
public class Orders
{
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Order
{
private uint salesOrderNumberField;
private uint purchaseOrderNumberField;
private ushort branchPlantField;
private OrderShipTo shipToField;
private byte quantityField;
private string uOMField;
private OrderDetail[] detailField;
/// <remarks/>
public uint SalesOrderNumber
{
get
{
return this.salesOrderNumberField;
}
set
{
this.salesOrderNumberField = value;
}
}
/// <remarks/>
public uint PurchaseOrderNumber
{
get
{
return this.purchaseOrderNumberField;
}
set
{
this.purchaseOrderNumberField = value;
}
}
/// <remarks/>
public ushort BranchPlant
{
get
{
return this.branchPlantField;
}
set
{
this.branchPlantField = value;
}
}
/// <remarks/>
public OrderShipTo ShipTo
{
get
{
return this.shipToField;
}
set
{
this.shipToField = value;
}
}
/// <remarks/>
public byte Quantity
{
get
{
return this.quantityField;
}
set
{
this.quantityField = value;
}
}
/// <remarks/>
public string UOM
{
get
{
return this.uOMField;
}
set
{
this.uOMField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Detail")]
public OrderDetail[] Detail
{
get
{
return this.detailField;
}
set
{
this.detailField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class OrderShipTo
{
private string line1Field;
private uint postalCodeField;
private string cityField;
private string stateField;
private string countryCodeField;
private string idField;
/// <remarks/>
public string Line1
{
get
{
return this.line1Field;
}
set
{
this.line1Field = value;
}
}
/// <remarks/>
public uint PostalCode
{
get
{
return this.postalCodeField;
}
set
{
this.postalCodeField = value;
}
}
/// <remarks/>
public string City
{
get
{
return this.cityField;
}
set
{
this.cityField = value;
}
}
/// <remarks/>
public string State
{
get
{
return this.stateField;
}
set
{
this.stateField = value;
}
}
/// <remarks/>
public string CountryCode
{
get
{
return this.countryCodeField;
}
set
{
this.countryCodeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string id
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class OrderDetail
{
private decimal lineNumberField;
private string gradeItemField;
private decimal quantityField;
private string uOMField;
private System.DateTime requestDateField;
private string statusField;
private System.DateTime createdField;
private string actionField;
/// <remarks/>
public decimal LineNumber
{
get
{
return this.lineNumberField;
}
set
{
this.lineNumberField = value;
}
}
/// <remarks/>
public string GradeItem
{
get
{
return this.gradeItemField;
}
set
{
this.gradeItemField = value;
}
}
/// <remarks/>
public decimal Quantity
{
get
{
return this.quantityField;
}
set
{
this.quantityField = value;
}
}
/// <remarks/>
public string UOM
{
get
{
return this.uOMField;
}
set
{
this.uOMField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(DataType = "date")]
public System.DateTime RequestDate
{
get
{
return this.requestDateField;
}
set
{
this.requestDateField = value;
}
}
/// <remarks/>
public string Status
{
get
{
return this.statusField;
}
set
{
this.statusField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public System.DateTime created
{
get
{
return this.createdField;
}
set
{
this.createdField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string action
{
get
{
return this.actionField;
}
set
{
this.actionField = value;
}
}
}
Just in case anyone ever stumbles across this problem. What was giving me hours of headache took 3 clicks to solve... Thanks all for your replies.

Missing properties in instance of class

I'm writing generic method in Android app, and I have a problem with missing properties.
My class has 7 public properties but when I'm trying to get all properties I'm getting list with one property.
Here is my code:
T item = (T)Activator.CreateInstance(typeof(T));
var properties = item.GetType().GetProperties();
Problem occurs in all classes.
I have the same code (also the same classes) in similar application for iOS and everything works fine.
Here is sample class:
public partial class DB_USER {
private int iD_USERField;
private int iD_ACTORField;
private System.Nullable<long> iD_DISTRIBUTORField;
private string lOGINField;
private string pASSWORDField;
private bool iS_BLOCKEDField;
private string dESCRIPTIONField;
/// <remarks/>
public int ID_USER {
get {
return this.iD_OPERATORField;
}
set {
this.iD_OPERATORField = value;
}
}
/// <remarks/>
public int ID_ACTOR {
get {
return this.iD_ACTORField;
}
set {
this.iD_ACTORField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public System.Nullable<long> ID_DISTRIBUTOR {
get {
return this.iD_DISTRIBUTORField;
}
set {
this.iD_DISTRIBUTORField = value;
}
}
/// <remarks/>
public string LOGIN {
get {
return this.lOGINField;
}
set {
this.lOGINField = value;
}
}
/// <remarks/>
public string PASSWORD {
get {
return this.pASSWORDField;
}
set {
this.pASSWORDField = value;
}
}
/// <remarks/>
public bool IS_BLOCKED {
get {
return this.iS_BLOCKEDField;
}
set {
this.iS_BLOCKEDField = value;
}
}
/// <remarks/>
public string DESCRIPTION {
get {
return this.dESCRIPTIONField;
}
set {
this.dESCRIPTIONField = value;
}
}
}

C# deserialization null elements

I´m trying to deserialize the following XML:
#"<Activity type=""WOActivity"">
<ActionID>1</ActionID>
<ActionLog></ActionLog>
<ActionLogSummary>Add subcomponent</ActionLogSummary>
<UserID></UserID>
<FlexFields>
<FlexField mappedTo=""STATUS"" id=""0"">WAPPR</FlexField>
<FlexField mappedTo=""WOSEQUENCE"" id=""0"">10</FlexField>
<FlexField mappedTo=""OWNERGROUP"" id=""0"">V-PSB-DE-HLC-HWSUPPORT</FlexField>
</FlexFields>
I´ve also the following class, which was generated by the xsd:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2", IsNullable = false)]
public partial class Activity {
private string actionIDField;
private string actionLogField;
private string actionLogSummaryField;
private System.DateTime logDateTimeField;
private bool logDateTimeFieldSpecified;
private System.DateTime scheduledStartDateTimeField;
private bool scheduledStartDateTimeFieldSpecified;
private System.DateTime scheduledEndDateTimeField;
private bool scheduledEndDateTimeFieldSpecified;
private System.DateTime workBeginDateTimeField;
private bool workBeginDateTimeFieldSpecified;
private System.DateTime workEndDateTimeField;
private bool workEndDateTimeFieldSpecified;
private string userIDField;
private string userNameField;
private FlexFieldsFlexField[] flexFieldsField;
private string activityTypeField;
private string typeField;
private string indexField;
/// <remarks/>
public string ActionID {
get {
return this.actionIDField;
}
set {
this.actionIDField = value;
}
}
/// <remarks/>
public string ActionLog {
get {
return this.actionLogField;
}
set {
this.actionLogField = value;
}
}
/// <remarks/>
///
[System.Xml.Serialization.XmlElement]
public string ActionLogSummary {
get {
return this.actionLogSummaryField;
}
set {
this.actionLogSummaryField = value;
}
}
/// <remarks/>
public System.DateTime LogDateTime {
get {
return this.logDateTimeField;
}
set {
this.logDateTimeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool LogDateTimeSpecified {
get {
return this.logDateTimeFieldSpecified;
}
set {
this.logDateTimeFieldSpecified = value;
}
}
/// <remarks/>
public System.DateTime ScheduledStartDateTime {
get {
return this.scheduledStartDateTimeField;
}
set {
this.scheduledStartDateTimeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool ScheduledStartDateTimeSpecified {
get {
return this.scheduledStartDateTimeFieldSpecified;
}
set {
this.scheduledStartDateTimeFieldSpecified = value;
}
}
/// <remarks/>
public System.DateTime ScheduledEndDateTime {
get {
return this.scheduledEndDateTimeField;
}
set {
this.scheduledEndDateTimeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool ScheduledEndDateTimeSpecified {
get {
return this.scheduledEndDateTimeFieldSpecified;
}
set {
this.scheduledEndDateTimeFieldSpecified = value;
}
}
/// <remarks/>
public System.DateTime WorkBeginDateTime {
get {
return this.workBeginDateTimeField;
}
set {
this.workBeginDateTimeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool WorkBeginDateTimeSpecified {
get {
return this.workBeginDateTimeFieldSpecified;
}
set {
this.workBeginDateTimeFieldSpecified = value;
}
}
/// <remarks/>
public System.DateTime WorkEndDateTime {
get {
return this.workEndDateTimeField;
}
set {
this.workEndDateTimeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool WorkEndDateTimeSpecified {
get {
return this.workEndDateTimeFieldSpecified;
}
set {
this.workEndDateTimeFieldSpecified = value;
}
}
/// <remarks/>
public string UserID {
get {
return this.userIDField;
}
set {
this.userIDField = value;
}
}
/// <remarks/>
public string UserName {
get {
return this.userNameField;
}
set {
this.userNameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("FlexField", IsNullable = false)]
public FlexFieldsFlexField[] FlexFields {
get {
return this.flexFieldsField;
}
set {
this.flexFieldsField = value;
}
}
/// <remarks/>
public string ActivityType {
get {
return this.activityTypeField;
}
set {
this.activityTypeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string type {
get {
return this.typeField;
}
set {
this.typeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(DataType = "integer")]
public string index {
get {
return this.indexField;
}
set {
this.indexField = value;
}
}
}
I´ve made a unit test, but it fails because all the elements are null (second assert and forth). The type attribute is deserialized just fine.
What could be possibly be wrong?
PS: I´ve tried to add the namespace "http://b2b.ibm.com/schema/B2B_CDM_Incident/R2_2" to the serializer with no success...
PS2: the serialization seems to be working just fine for this class
Thanks.
string result = #"<Activity type=""WOActivity"">
<ActionID>1</ActionID>
<ActionLog></ActionLog>
<ActionLogSummary>Add subcomponent</ActionLogSummary>
<UserID></UserID>
<FlexFields>
<FlexField mappedTo=""STATUS"" id=""0"">WAPPR</FlexField>
<FlexField mappedTo=""WOSEQUENCE"" id=""0"">10</FlexField>
<FlexField mappedTo=""OWNERGROUP"" id=""0"">V-PSB-DE-HLC-HWSUPPORT</FlexField>
</FlexFields>
</Activity>";
var serializer = new XmlSerializer(typeof (Activity), new XmlRootAttribute("Activity"));
var first = (Activity)serializer.Deserialize(new XmlTextReader(new StringReader(result)));
Assert.AreEqual("WOActivity", first.type);
Assert.AreEqual("Add subcomponent", first.ActionLogSummary);
Assert.IsNotNull(first.FlexFields);
Assert.AreEqual(4, first.FlexFields.Count());
Just put the root element into the correct namespace:
string xml = #"<Activity type=""WOActivity""
xmlns=""http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2"">
...
</Activity>";
Note that because the namespace is inherited, everything else also uses that element.
This then works:
var ser = new XmlSerializer(typeof(Activity));
var activity = (Activity)ser.Deserialize(new StringReader(xml));
System.Console.WriteLine(activity.ActionID);
System.Console.WriteLine(activity.ActionLogSummary);
System.Console.WriteLine(activity.type);
with output:
1
Add subcomponent
WOActivity
In other scenarios, you may need to refer to multiple namespaces, or mention the same namespace multiple times. Then it becomes useful to declare an alias; the following is semantically identical to the first example in this answer:
string xml = #"<b2b:Activity type=""WOActivity""
xmlns:b2b=""http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2"">
<b2b:ActionID>1</b2b:ActionID>
<b2b:ActionLog></b2b:ActionLog>
<b2b:ActionLogSummary>Add subcomponent</b2b:ActionLogSummary>
...
</b2b:Activity>";
With the only difference that we can now use b2b: as a prefix on any element as an alternative to saying xmlns=""http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2"". Note also that alias-based namespaces are not inherited, unlike xmlns= namespaces.
just delete the two generated lines:
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://b2b.ibm.com/schema/IS_B2B_CDM/R2_2", IsNullable = false)]

Error while reading a Array from C# assembly registered as COM in VBScript

I have used the xsd.exe program to create a class hierarchy for a xsd file. I am successfully able to deserialize a xml file and read values from it in C#. However when i register the library and am trying to read array values from VBScript it fails.
I get Wrong number of arguments or invalid property assignment error. I am however able to read the values of simple properties.
Here is my class hierarchy
using System.Xml.Serialization;
public partial class AppEntryDefinition {
private ProductDefinition productDefinitionField;
private ViewSection[] viewDefinitionField;
public ProductDefinition productDefinition {
get {
return this.productDefinitionField;
}
set {
this.productDefinitionField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("viewSection", IsNullable=false)]
public ViewSection[] viewDefinition {
get {
return this.viewDefinitionField;
}
set {
this.viewDefinitionField = value;
}
}
}
public partial class ProductDefinition {
private int kindCodeField;
private string productCodeField;
private string productTitleField;
private string adminSystemField;
private string vapCodeField;
private Features featuresField;
private RuleSet[] ruleSetField;
/// <remarks/>
public int kindCode {
get {
return this.kindCodeField;
}
set {
this.kindCodeField = value;
}
}
/// <remarks/>
public string productCode {
get {
return this.productCodeField;
}
set {
this.productCodeField = value;
}
}
/// <remarks/>
public string productTitle {
get {
return this.productTitleField;
}
set {
this.productTitleField = value;
}
}
/// <remarks/>
public string adminSystem {
get {
return this.adminSystemField;
}
set {
this.adminSystemField = value;
}
}
/// <remarks/>
public string vapCode {
get {
return this.vapCodeField;
}
set {
this.vapCodeField = value;
}
}
/// <remarks/>
public Features features {
get {
return this.featuresField;
}
set {
this.featuresField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("ruleSet")]
public RuleSet[] ruleSet {
get {
return this.ruleSetField;
}
set {
this.ruleSetField = value;
}
}
}
public partial class RuleSet {
private Rule[] ruleField;
private string phaseField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("rule")]
public Rule[] rule {
get {
return this.ruleField;
}
set {
this.ruleField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string phase {
get {
return this.phaseField;
}
set {
this.phaseField = value;
}
}
}
public partial class Rule {
private Case[] caseField;
private string nameField;
private string typeField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("case")]
public Case[] #case {
get {
return this.caseField;
}
set {
this.caseField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string type {
get {
return this.typeField;
}
set {
this.typeField = value;
}
}
}
Here is my code which deserializes my xml to objects
namespace CustomUtilities
{
public class XmlSerializer
{
public AppEntryDefinition Deserialize(String xmlPath)
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(AppEntryDefinition));
AppEntryDefinition aed = null;
aed = (AppEntryDefinition)serializer.Deserialize(new System.IO.StreamReader(xmlPath));
return aed;
}
}
}
Here is my vbscript code
Dim obj, objAppEntry
Set obj = CreateObject("CustomUtilities.XmlSerializer")
Set objAppEntry = obj.Deserialize("C:\Users\xx\Desktop\schema\xx.xml")
Set xxx = objAppEntry.productDefinition.ruleSet
Yes, these arrays will not get through from NET to VBScript as they are not COM automation compatible.
What you can do, though, is create a partial class with the same name as the initial one, duplicate the array properties, give them another name, and declare them as a type that can be used in automation (and recompile the whole thing). You could create a custom type (it's necessary if yuo don't want to duplicate the values), but the easiest way to do it is to reuse the "old" ArrayList class. It's marked as COM visible and it can be used easily from a script language.
So here is a sample partial add-on:
public partial class ProductDefinition
{
[XmlIgnore]
public ArrayList ruleSetArrayList
{
get
{
return new ArrayList(ruleSet);
}
}
}
And the script that uses it:
Set xxx = objAppEntry.productDefinition.ruleSetArrayList
for each item in xxx
WScript.echo item.phase
next

Categories