Avatar of psdesignadmin
psdesignadmin
Flag for United States of America asked on

C# Finding Value in Parent / Multiple Child objects Returning Child values

I have filled the following Parent Class and Multiple Child classes from XML data.

Parent Class (Materials.cs):

using System;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JobInvoicerCS
{
	[XmlRoot(ElementName="Materials")]
	public class Materials
    {
		[XmlElement(ElementName="WF")]
		public List<WF> WF { get; set; }
		[XmlElement(ElementName="M")]
		public List<M> M { get; set; }
		[XmlElement(ElementName="S")]
		public List<S> S { get; set; }
		[XmlElement(ElementName="HP")]
		public List<HP> HP { get; set; }
		[XmlElement(ElementName="WT")]
		public List<WT> WT { get; set; }
		[XmlElement(ElementName="MT")]
		public List<MT> MT { get; set; }
		[XmlElement(ElementName="ST")]
		public List<ST> ST { get; set; }
		[XmlElement(ElementName="C")]
		public List<C> C { get; set; }
		[XmlElement(ElementName="MC")]
		public List<MC> MC { get; set; }
		[XmlElement(ElementName="TS")]
		public List<TS> TS { get; set; }
		[XmlElement(ElementName="TSR")]
		public List<TSR> TSR { get; set; }
		[XmlElement(ElementName="Pipe")]
		public List<Pipe> Pipe { get; set; }
		[XmlElement(ElementName="Angle")]
		public List<Angle> Angle { get; set; }
		[XmlElement(ElementName="DoubleAngle")]
		public List<DoubleAngle> DoubleAngle { get; set; }
	}
}

Open in new window


Here is one child class (WF.cs):

using System;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JobInvoicerCS
{
    [XmlRoot(ElementName = "WF")]
    public class WF
    {
        [XmlElement(ElementName = "Size")]
        public string Size { get; set; }
        [XmlElement(ElementName = "A")]
        public string A { get; set; }
        [XmlElement(ElementName = "d")]
        public string D { get; set; }
        [XmlElement(ElementName = "tw")]
        public string Tw { get; set; }
        [XmlElement(ElementName = "bf")]
        public string Bf { get; set; }
        [XmlElement(ElementName = "tf")]
        public string Tf { get; set; }
        [XmlElement(ElementName = "k_des")]
        public string K_des { get; set; }
        [XmlElement(ElementName = "k_det")]
        public string K_det { get; set; }
        [XmlElement(ElementName = "k1")]
        public string K1 { get; set; }
        [XmlElement(ElementName = "T")]
        public string T { get; set; }
        [XmlElement(ElementName = "gage")]
        public string Gage { get; set; }
        [XmlElement(ElementName = "wt__ft")]
        public string Wt__ft { get; set; }
        [XmlElement(ElementName = "bf__2_tf")]
        public string Bf__2_tf { get; set; }
        [XmlElement(ElementName = "h_tw")]
        public string H_tw { get; set; }
        [XmlElement(ElementName = "Ix")]
        public string Ix { get; set; }
        [XmlElement(ElementName = "Sx")]
        public string Sx { get; set; }
        [XmlElement(ElementName = "rx")]
        public string Rx { get; set; }
        [XmlElement(ElementName = "Zx")]
        public string Zx { get; set; }
        [XmlElement(ElementName = "Iy")]
        public string Iy { get; set; }
        [XmlElement(ElementName = "Sy")]
        public string Sy { get; set; }
        [XmlElement(ElementName = "ry")]
        public string Ry { get; set; }
        [XmlElement(ElementName = "Zy")]
        public string Zy { get; set; }
        [XmlElement(ElementName = "rts")]
        public string Rts { get; set; }
        [XmlElement(ElementName = "ho")]
        public string Ho { get; set; }
        [XmlElement(ElementName = "J")]
        public string J { get; set; }
        [XmlElement(ElementName = "Cw")]
        public string Cw { get; set; }
        [XmlElement(ElementName = "Wno")]
        public string Wno { get; set; }
        [XmlElement(ElementName = "Sw1")]
        public string Sw1 { get; set; }
        [XmlElement(ElementName = "Qf")]
        public string Qf { get; set; }
        [XmlElement(ElementName = "Qw")]
        public string Qw { get; set; }
    }
}

Open in new window


I am attaching the XML and the other child classes for brevity.

I am trying to find values contained in the sub-classes if they contain a certain Size.  Each sub-class contains a Size property but will not know if they are WF, WT, C, etc.

For example:

Need to return all values in the query if Size = "W12x40".  I know this would be a WF, the query should return all properties for that size.

I fill the Parent Children using this code:

            string path = @"XmlFiles\Materials.xml";
            XmlSerializer serial = new XmlSerializer(typeof(Materials));
            StreamReader reader = new StreamReader(path);
            
            StructuralMaterials = (Materials)serial.Deserialize(reader);
            reader.Close();

Open in new window


I will not know what subclass the size will be in on all cases. I am also not sure if I should change my structures to improve this portion of my code.

Materials.xml
Angle.cs
C.cs
DoubleAngle.cs
M.cs
HP.cs
MC.cs
MT.cs
Pipe.cs
S.cs
ST.cs
TS.cs
TSR.cs
WT.cs
C#.NET ProgrammingXML

Avatar of undefined
Last Comment
psdesignadmin

8/22/2022 - Mon
it_saige

You want to use something like:
var W12x40 = (from material in StructuralMaterials.WF where material.Size.Equals("W12x40", StringComparison.OrdinalIgnoreCase) select material);

Open in new window

Proof of concept -
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace EE_Q28909285
{
	class Program
	{
		private static Materials StructuralMaterials;
		static void Main(string[] args)
		{
			string path = @"Materials.xml";
			XmlSerializer serial = new XmlSerializer(typeof(Materials));
			StreamReader reader = new StreamReader(path);
			StructuralMaterials = (Materials)serial.Deserialize(reader);
			reader.Close();
			var W12x40 = (from material in StructuralMaterials.WF where material.Size.Equals("W12x40", StringComparison.OrdinalIgnoreCase) select material);
			foreach (var material in W12x40)
				Console.WriteLine(material);
			Console.ReadLine();
		}
	}

	[XmlRoot(ElementName = "Materials")]
	public class Materials
	{
		[XmlElement(ElementName = "WF")]
		public List<WF> WF { get; set; }
	}

	[XmlRoot(ElementName = "WF")]
	public class WF
	{
		[XmlElement(ElementName = "Size")]
		public string Size { get; set; }
		[XmlElement(ElementName = "A")]
		public string A { get; set; }
		[XmlElement(ElementName = "d")]
		public string D { get; set; }
		[XmlElement(ElementName = "tw")]
		public string Tw { get; set; }
		[XmlElement(ElementName = "bf")]
		public string Bf { get; set; }
		[XmlElement(ElementName = "tf")]
		public string Tf { get; set; }
		[XmlElement(ElementName = "k_des")]
		public string K_des { get; set; }
		[XmlElement(ElementName = "k_det")]
		public string K_det { get; set; }
		[XmlElement(ElementName = "k1")]
		public string K1 { get; set; }
		[XmlElement(ElementName = "T")]
		public string T { get; set; }
		[XmlElement(ElementName = "gage")]
		public string Gage { get; set; }
		[XmlElement(ElementName = "wt__ft")]
		public string Wt__ft { get; set; }
		[XmlElement(ElementName = "bf__2_tf")]
		public string Bf__2_tf { get; set; }
		[XmlElement(ElementName = "h_tw")]
		public string H_tw { get; set; }
		[XmlElement(ElementName = "Ix")]
		public string Ix { get; set; }
		[XmlElement(ElementName = "Sx")]
		public string Sx { get; set; }
		[XmlElement(ElementName = "rx")]
		public string Rx { get; set; }
		[XmlElement(ElementName = "Zx")]
		public string Zx { get; set; }
		[XmlElement(ElementName = "Iy")]
		public string Iy { get; set; }
		[XmlElement(ElementName = "Sy")]
		public string Sy { get; set; }
		[XmlElement(ElementName = "ry")]
		public string Ry { get; set; }
		[XmlElement(ElementName = "Zy")]
		public string Zy { get; set; }
		[XmlElement(ElementName = "rts")]
		public string Rts { get; set; }
		[XmlElement(ElementName = "ho")]
		public string Ho { get; set; }
		[XmlElement(ElementName = "J")]
		public string J { get; set; }
		[XmlElement(ElementName = "Cw")]
		public string Cw { get; set; }
		[XmlElement(ElementName = "Wno")]
		public string Wno { get; set; }
		[XmlElement(ElementName = "Sw1")]
		public string Sw1 { get; set; }
		[XmlElement(ElementName = "Qf")]
		public string Qf { get; set; }
		[XmlElement(ElementName = "Qw")]
		public string Qw { get; set; }
	}
}

Open in new window

Produces the following output -Capture.JPGWhich means that I am getting back only one match.  I can access this match's properties; e.g. -
foreach (var material in W12x40)
	Console.WriteLine("A: {0}; Bf: {1}; etc.", material.A, material.Bf);

Open in new window

Which now produces -Capture.JPG-saige-
ste5an

The solution is already in your question:
I will not know what subclass the size will [..]
Just use sub-classing. As each class has a size, it must be derived from a class BaseElement, which contains all common fields.

Then you can use LINQ and query on Size.

Do you have a XSD for that XML?

btw, you don't need all the XmlElement attributes, cause your properties have the same name.
psdesignadmin

ASKER
Ok, but what if I did not know the W12x40 was in the WF? I want to search all the materials to find the member that has a Size of W12x40 and return all properties for that member.

Let say:

string MatSize = "W12x40";

then something like:

object Member = if (.Size == MatSize)

I am not sure how to get past the Unknown in materials.unknown.size.  I want to find the object without knowing if the Unknown is a WF, WT, C, MC, etc. Unless I setup my original materials import incorrectly.  I am using my XML to store all the data that will be used later in memory.
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
ste5an

As I said use sub-classing. btw, you common fields are A, Size and wt__ft.
psdesignadmin

ASKER
ste5an,

As I said use sub-classing...

I am sorry for my ignorance, can you explain what you mean by sub-classing?
ASKER CERTIFIED SOLUTION
ste5an

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
psdesignadmin

ASKER
Can you attach the SimplifiedMaterials.xml?  I would like to see how you modified it.  I think I understand.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
ste5an

psdesignadmin

ASKER
Good explanation.  I understand how I need to modify and go forward. Thanks!