C# XML Parsing with multiple nodes - c#

I have a file that is formatted roughly like:
what i want to do is get the Type element then get the data for each source and output it to text fields.
Cant seem to get it working.`
What is the best way to parse this?
<Config>
<Type>8_Port_Switch</Type> `
<Inputs>
<Source_1>
<Source_1_Name>BobsPC</Source_1_Name>
<Source_1_Input>7</Source_1_Input>
</Source_1>
<Source_2>
<Source_2_Name>Office</Source_2_Name>
<Source_2_Input>4</Source_2_Input>
</Source_2>
<Source_3>
<Source_3_Name>Printer</Source_3_Name>
<Source_3_Input>3</Source_3_Input>
</Source_3>
</Config>
this file can be up to 32 ports. I want to use the type info to force a particular form to open then populate the form with the results of the read.
i have a label for each source and 2 text boxes for Name and Input that i want to populate
for example. I want to read the data and populate:
enter image description here
edit the information.
Then create a new xml doc and upload to the server. I can create with no issues. Its just reading it and passing it back into the fields.

Option 1
I think a clean approach will be to throw the contents of your XML into a DataSet and then bind your form's controls to the table. Here is an example to help you:
DataSet ds = new DataSet();
ds.readxml("XML File Path");
var bs = new BindingSource();
bs.DataSource = ds;
bs.DataMember = ds.table[0].tablename;
textBox1.DataBindings.Add("FirstName", bs, "Table Name");
textBox2.DataBindings.Add("FirstName", bs, "Table Name");
Option 2
You can use my answer here to create a C# class for your xml. Then deserialize the xml contents into the C# class. Once you have deserialized it into the C# class, you can work and manipulate the instance of the class. You can even bind the instance to your form. The form controls can change the contents of the instance like any C# class instance.
Once you are done, you can then serialize back to xml. Here is the class that was generated for your XML:
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Config
{
private string typeField;
private ConfigInputs inputsField;
/// <remarks/>
public string Type
{
get
{
return this.typeField;
}
set
{
this.typeField = value;
}
}
/// <remarks/>
public ConfigInputs Inputs
{
get
{
return this.inputsField;
}
set
{
this.inputsField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigInputs
{
private ConfigInputsSource_1 source_1Field;
private ConfigInputsSource_2 source_2Field;
private ConfigInputsSource_3 source_3Field;
/// <remarks/>
public ConfigInputsSource_1 Source_1
{
get
{
return this.source_1Field;
}
set
{
this.source_1Field = value;
}
}
/// <remarks/>
public ConfigInputsSource_2 Source_2
{
get
{
return this.source_2Field;
}
set
{
this.source_2Field = value;
}
}
/// <remarks/>
public ConfigInputsSource_3 Source_3
{
get
{
return this.source_3Field;
}
set
{
this.source_3Field = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigInputsSource_1
{
private string source_1_NameField;
private byte source_1_InputField;
/// <remarks/>
public string Source_1_Name
{
get
{
return this.source_1_NameField;
}
set
{
this.source_1_NameField = value;
}
}
/// <remarks/>
public byte Source_1_Input
{
get
{
return this.source_1_InputField;
}
set
{
this.source_1_InputField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigInputsSource_2
{
private string source_2_NameField;
private byte source_2_InputField;
/// <remarks/>
public string Source_2_Name
{
get
{
return this.source_2_NameField;
}
set
{
this.source_2_NameField = value;
}
}
/// <remarks/>
public byte Source_2_Input
{
get
{
return this.source_2_InputField;
}
set
{
this.source_2_InputField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ConfigInputsSource_3
{
private string source_3_NameField;
private byte source_3_InputField;
/// <remarks/>
public string Source_3_Name
{
get
{
return this.source_3_NameField;
}
set
{
this.source_3_NameField = value;
}
}
/// <remarks/>
public byte Source_3_Input
{
get
{
return this.source_3_InputField;
}
set
{
this.source_3_InputField = value;
}
}
}
Your xml had some errors and I had to fix them such as the closing tags were missing. Then I used the following code to change one thing and then resave it. It worked:
var serializer = new XmlSerializer(typeof(Config));
var reader = new StreamReader("StackQuestion.xml");
var result = serializer.Deserialize(reader) as Config;
reader.Close();
result.Inputs.Source_1.Source_1_Name = "CodingYoshi";
serializer.Serialize(new StreamWriter("StackQuestion.xml"), result);

Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("Config").Select(x => new {
name = (string)x.Element("Type"),
type = x.Element("Inputs").Elements().Select(y => new
{
id = y.Name.LocalName,
name = (string)y.Elements().First(),
input = (int)y.Elements().Last()
}).ToList()
}).ToList();
}
}
}

Related

How to desalinize an xml and pass it through wcf service in c#

I have an xml as shown below and want to pass it as a response from wcf service.What i did is, i used Visual studio to generate c# classes from xml and then deserilize the xml with the classes generated from VS.Data is coming in Soap UI from WCF service but when i click validate in soap ui, it is throwing error
EDIT on 250320
Finally i reached to single error like
line 17: Invalid xsi:type qname: 'c:string' in element SITE_NAME#http://schemas.datacontract.org/2004/07/ITSM_GIS_NRMIntegration.BusinessObjects
c# code
namespace ITSM_GIS_NRMIntegration
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class GisItsmService : IGisItsmService
{
Datatable dtcustomerSiteDtls = dtcustomerSiteDtls.AsEnumerable()
.OrderBy(x => x.Field<string>("CBCM_PARTY_ID"))
.ThenBy(x => x.Field<string>("CBCM_PARTY_NAME"))
.ThenBy(x => x.Field<string>("SERVICE"))
.ThenBy(x => x.Field<string>("SITENAME"))
.ThenBy(x => x.Field<string>("NODENAME"))
.CopyToDataTable();
XElement allSites = doc.Root;
foreach (var idGroup in dtcustomerSiteDtls.AsEnumerable().GroupBy(x => x.Field<string>("CBCM_PARTY_ID")))
{
XElement siteNode = new XElement("PARTY_SITE_NODES");
allSites.Add(siteNode);
siteNode.Add(new XElement("CBCM_PARTY_ID", idGroup.Key));
siteNode.Add(new XElement("CBCM_PARTY_NAME", idGroup.First().Field<string>("CBCM_PARTY_NAME")));
DataTable dtfilter = dtcustomerSiteDtls.Select("CBCM_PARTY_ID = '" + idGroup.Key.ToString() + "'").CopyToDataTable();
foreach (var service in dtfilter.AsEnumerable().GroupBy(x => x.Field<string>("SERVICE")))
{
XElement partyServices = new XElement("PARTY_SERVICES");
siteNode.Add(partyServices);
partyServices.Add(new XElement("SERVICE_NAME", service.Key));
XElement serviceSites = new XElement("SERVICE_SITES");
partyServices.Add(serviceSites);
foreach (var serviceSite in service.GroupBy(x => x.Field<string>("SITENAME")))
{
serviceSites.Add(new XElement("SITE_NAME", serviceSite.Key));
XElement siteNodes = new XElement("SITE_NODES");
serviceSites.Add(siteNodes);
string[] nodeNames = serviceSite.Select(x => x.Field<string>("NODENAME")).Distinct().ToArray();
foreach (string nodeName in nodeNames)
{
siteNodes.Add(new XElement("NODE_NAME", nodeName));
}
}
}
}
}
}
catch (Exception ex)
{
log.Error(ex.Message);
}
XmlSerializer myItemSerializer = new XmlSerializer(typeof(getCustomerSites));
using (var reader = doc.CreateReader())
{
sitedetailsResObj = (getCustomerSites)myItemSerializer.Deserialize(reader);
}
C# classes used to serialize
namespace ITSM_GIS_NRMIntegration.BusinessObjects
{
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class getCustomerSites:ResponseBase
{
private getCustomerSitesPARTY_SITE_NODES[] pARTY_SITE_NODESField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("PARTY_SITE_NODES")]
public getCustomerSitesPARTY_SITE_NODES[] PARTY_SITE_NODES
{
get
{
return this.pARTY_SITE_NODESField;
}
set
{
this.pARTY_SITE_NODESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODES
{
private uint cBCM_PARTY_IDField;
private string cBCM_PARTY_NAMEField;
private getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES[] pARTY_SERVICESField;
/// <remarks/>
public uint CBCM_PARTY_ID
{
get
{
return this.cBCM_PARTY_IDField;
}
set
{
this.cBCM_PARTY_IDField = value;
}
}
/// <remarks/>
public string CBCM_PARTY_NAME
{
get
{
return this.cBCM_PARTY_NAMEField;
}
set
{
this.cBCM_PARTY_NAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("PARTY_SERVICES")]
public getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES[] PARTY_SERVICES
{
get
{
return this.pARTY_SERVICESField;
}
set
{
this.pARTY_SERVICESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES
{
private string sERVICE_NAMEField;
private getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES sERVICE_SITESField;
/// <remarks/>
public string SERVICE_NAME
{
get
{
return this.sERVICE_NAMEField;
}
set
{
this.sERVICE_NAMEField = value;
}
}
/// <remarks/>
public getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES SERVICE_SITES
{
get
{
return this.sERVICE_SITESField;
}
set
{
this.sERVICE_SITESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[KnownType(typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES
{
private object[] sITE_NAMEField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("SITE_NAME", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("SITE_NODES", typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public object[] SITE_NAME
{
get
{
return this.sITE_NAMEField;
}
set
{
this.sITE_NAMEField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES
{
private string[] nODE_NAMEField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("NODE_NAME")]
public string[] NODE_NAME
{
get
{
return this.nODE_NAMEField;
}
set
{
this.nODE_NAMEField = value;
}
}
}
Error in SOAP UI is as shown below
An
Why aren't you using two properties instead of one?
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES
{
private object[] itemNamesField;
private object[] itemNodessField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("SITE_NAME", typeof(string))]
public object[] ItemNames
{
get
{
return this.itemNamesField;
}
set
{
this.itemNamesField = value;
}
}
[System.Xml.Serialization.XmlElementAttribute("SITE_NODES", typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public object[] ItemNodes
{
get
{
return this.itemNodesField;
}
set
{
this.itemNodesField = value;
}
}
}
Below is the code to deserialize the xml. Linq is much faster to deserialize than the code below. So you have to decide if it is better to use your code or the code below. Usually I recommend if you have a schema (and the classes) and trying to get all the data it is better to use serialization. You are putting results into a datatable which I then recommend xml linq. I just want to so why I suggested to remove the base class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(getCustomerSites));
getCustomerSites sites = (getCustomerSites)serializer.Deserialize(reader);
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class getCustomerSites //: ResponseBase
{
private getCustomerSitesPARTY_SITE_NODES[] pARTY_SITE_NODESField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("PARTY_SITE_NODES")]
public getCustomerSitesPARTY_SITE_NODES[] PARTY_SITE_NODES
{
get
{
return this.pARTY_SITE_NODESField;
}
set
{
this.pARTY_SITE_NODESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODES
{
private uint cBCM_PARTY_IDField;
private string cBCM_PARTY_NAMEField;
private getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES[] pARTY_SERVICESField;
/// <remarks/>
public uint CBCM_PARTY_ID
{
get
{
return this.cBCM_PARTY_IDField;
}
set
{
this.cBCM_PARTY_IDField = value;
}
}
/// <remarks/>
public string CBCM_PARTY_NAME
{
get
{
return this.cBCM_PARTY_NAMEField;
}
set
{
this.cBCM_PARTY_NAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("PARTY_SERVICES")]
public getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES[] PARTY_SERVICES
{
get
{
return this.pARTY_SERVICESField;
}
set
{
this.pARTY_SERVICESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES
{
private string sERVICE_NAMEField;
private getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES sERVICE_SITESField;
/// <remarks/>
public string SERVICE_NAME
{
get
{
return this.sERVICE_NAMEField;
}
set
{
this.sERVICE_NAMEField = value;
}
}
/// <remarks/>
public getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES SERVICE_SITES
{
get
{
return this.sERVICE_SITESField;
}
set
{
this.sERVICE_SITESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
//[KnownType(typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES
{
private object[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("SITE_NAME", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("SITE_NODES", typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public object[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES
{
private string[] nODE_NAMEField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("NODE_NAME")]
public string[] NODE_NAME
{
get
{
return this.nODE_NAMEField;
}
set
{
this.nODE_NAMEField = value;
}
}
}
}

Parse JCR XML export in C#

I received some XML files from a customer that I need to process in C#. Looking at the structure and doing some googleing it seems that this content has been exported from JCR (I haven't worked with this at all so I might be wrong).
The structure looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<sv:node xmlns:sv="http://www.jcp.org/jcr/sv/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" sv:name="foodtruck-gruener-sepp">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>mgnl:Event</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name" sv:multiple="true">
<sv:value>mgnl:hasVersion</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>6371704f-1cc4-4ab9-9298-43c9dd4f79ab</sv:value>
</sv:property>
<sv:property sv:name="name" sv:type="String">
<sv:value>user name</sv:value>
</sv:property>
<sv:property sv:name="email" sv:type="String">
<sv:value>info#somedomain.com</sv:value>
</sv:property>
</sv:node>
How would I go about parsing this? Can this be done by just using XMLElementAttribute with XmlSerializer?
The code below uses xml linq and puts results into a dictionary. The code does not parse the xml Type attribute
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement node = doc.Root;
XNamespace sv = node.GetNamespaceOfPrefix("sv");
Dictionary<string, string> dict = doc.Descendants(sv + "property")
.GroupBy(x => (string)x.Attribute(sv + "name"), y => (string)y.Element(sv + "value"))
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}
have to create a class with the same type of XML, that can be generated through visual studio Edit> Paste Special to deserialize it.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.jcp.org/jcr/sv/1.0")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.jcp.org/jcr/sv/1.0", IsNullable = false)]
public partial class node
{
private nodeProperty[] propertyField;
private string nameField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("property")]
public nodeProperty[] property
{
get
{
return this.propertyField;
}
set
{
this.propertyField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
public string name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.jcp.org/jcr/sv/1.0")]
public partial class nodeProperty
{
private string valueField;
private string nameField;
private string typeField;
private bool multipleField;
private bool multipleFieldSpecified;
/// <remarks/>
public string value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
public string name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
public string type
{
get
{
return this.typeField;
}
set
{
this.typeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
public bool multiple
{
get
{
return this.multipleField;
}
set
{
this.multipleField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool multipleSpecified
{
get
{
return this.multipleFieldSpecified;
}
set
{
this.multipleFieldSpecified = value;
}
}
}

How to deserialize XML document with inner tags and inner elements?

This is my XML file.
<getMetadata>
<Project Name="Doors_Demo">
<Module FullPath="/Doors_Demo/Test_Module2">
<Attributes>
<Attribute name="TableType" type="TableType" />
<Attribute name="TableTopBorder" type="TableEdgeType" />
</Attributes>
</Module>
</Project>
</getMetadata>
I want to deserialize the above XML
Below is my code:
[XmlRoot("getMetadata")]
public class RootClass
{
public Project element_Project;
[XmlElement("Project")]
public Project Project
{
get { return element_Project; }
set { element_Project = value; }
}
}
public class Project
{
public string name;
[XmlAttribute("Name")]
public string Id
{
get { return name; }
set { name = value; }
}
}
public static void Main(string[] args)
{
RootClass obj = new RootClass();
XmlSerializer serializer = new XmlSerializer(typeof(RootClass));
using (FileStream stream = new FileStream(#"E:\getMetadata(4).xml", FileMode.Open))
{
RootClass myxml = (RootClass)serializer.Deserialize(stream);
Console.WriteLine(myxml.Project.name);
}
}
I want to deserialize my XML into a list, I am not able to access all inner elements and attributes inside the root element.
I want details of module element and its inner elements and tags into list which can be accessed.
Here is a little trick to generate classes from your XML automatically.
First, create a new empty class, name it for example TempXml.
Copy your XML to the clipboard and open the new empty class you just created.
Go to Visual Studio Edit menu then Paste Special and Paste XML as Classes:
This will generate the following code:
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class getMetadata
{
private getMetadataProject projectField;
/// <remarks/>
public getMetadataProject Project
{
get
{
return this.projectField;
}
set
{
this.projectField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getMetadataProject
{
private getMetadataProjectModule moduleField;
private string nameField;
/// <remarks/>
public getMetadataProjectModule Module
{
get
{
return this.moduleField;
}
set
{
this.moduleField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getMetadataProjectModule
{
private getMetadataProjectModuleAttribute[] attributesField;
private string fullPathField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("Attribute", IsNullable = false)]
public getMetadataProjectModuleAttribute[] Attributes
{
get
{
return this.attributesField;
}
set
{
this.attributesField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string FullPath
{
get
{
return this.fullPathField;
}
set
{
this.fullPathField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getMetadataProjectModuleAttribute
{
private string nameField;
private string typeField;
/// <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;
}
}
}
Which should work fine with the XmlSerializer class.
You can clean up a little bit the generated output by removing the empty remarks, changing the name of the classes to use camel case (in this case you need to specify the real element name in the attribute as you were doing in your question) or move the classes to different files.
Hope it helps.

Initialize a xml class obtained from Edit, Paste Special, Paste XML as Classes

I have a class generated from "Edit, Paste Special, Paste XML as Classes." like explains here. Generating Data Type Classes from XML
XML:
<?xml version="1.0"?>
<Items version="1.0">
<Item InputFileName="G:\FileFile.txt">
<Position X="500" Y="100" Z="150"/>
</Item>
</Items>
Class:
namespace Produccion.ClassFile
{
/// <comentarios/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Items
{
private ItemsItem[] itemField;
private decimal versionField;
/// <comentarios/>
[System.Xml.Serialization.XmlElementAttribute("Item")]
public ItemsItem[] Item
{
get
{
return this.itemField;
}
set
{
this.itemField = value;
}
}
/// <comentarios/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal version
{
get
{
return this.versionField;
}
set
{
this.versionField = value;
}
}
}
/// <comentarios/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ItemsItem
{
private ItemsItemPosition positionField;
private string inputFileNameField;
/// <comentarios/>
public ItemsItemPosition Position
{
get
{
return this.positionField;
}
set
{
this.positionField = value;
}
}
/// <comentarios/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string InputFileName
{
get
{
return this.inputFileNameField;
}
set
{
this.inputFileNameField = value;
}
}
}
/// <comentarios/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ItemsItemPosition
{
private decimal xField;
private decimal yField;
private decimal zField;
/// <comentarios/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal X
{
get
{
return this.xField;
}
set
{
this.xField = value;
}
}
/// <comentarios/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal Y
{
get
{
return this.yField;
}
set
{
this.yField = value;
}
}
/// <comentarios/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal Z
{
get
{
return this.zField;
}
set
{
this.zField = value;
}
}
}
}
I don't know how I can initialize this class with data from file.
Deserialization is the process of reading an XML document and constructing an object that is strongly typed to the XML Schema (XSD) of the document.
You would do something like this
XmlSerializer serializer = new XmlSerializer(typeof(Items));
// Declare an object variable of the type to be deserialized.
Items i;
using (Stream reader = new FileStream(filename, FileMode.Open))
{
// Call the Deserialize method to restore the object's state.
i = (Items)serializer.Deserialize(reader);
}
You are likely an expert now...(Years later, a newbie answers) I couldn't find the solution to how to use Paste Special XML, I was getting "Object reference not set to an instance of an object". This was when my XML had an attribute and an Element (I was using VB). I realized VS did not initialize the variable [Name]Field. So I just added As New for the [Name][Name] class. In your case, New ItemsItemPosition.

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