0

I'm having some issues with this query I've been trying and searching a solution since Friday.

I have an xml file like this:

<?xml version="1.0" encoding="utf-8"?>
    <ObjectPropertyModule Project="PROJECT NAME" xmlns:dt="urn:schemas-microsoft-com:datatypes">
        <Classes>
            <Class name="class_name_1">
                <Objects>
                    <Object name="obj_name_1">
                        <Properties>
                            <Property name="prop_A" dt:dt="string">value_A1</Property>
                            <Property name="prop_B" dt:dt="string">value_B1</Property>
                        </Properties>
                    </Object>
                    <Object name="obj_name_2">
                        <Properties>
                            <Property name="prop_A" dt:dt="string">value_A2</Property>
                            <Property name="prop_B" dt:dt="string">value_B2</Property>
                        </Properties>
                    </Object>
                    <Object name="obj_name_3">
                        <Properties>
                            <Property name="prop_A" dt:dt="string">value_A3</Property>
                            <Property name="prop_B" dt:dt="string">value_B3</Property>
                        </Properties>
                    </Object>
                    <Object name="obj_name_N">
                        <Properties>
                            <Property name="prop_A" dt:dt="string">value_AN</Property>
                            <Property name="prop_B" dt:dt="string">value_BN</Property>
                        </Properties>                               
                    </Object>
                </Objects>
            </Class>
            <Class name="class_name_2">
            <Objects>...</Objects>
            </Class>
            <Class name="class_name_3">
            <Objects>...</Objects>
            </Class>
        </Classes>
    </ObjectPropertyModule>

I need to have a list with anon objects like this:

class_name_1_List()
el_1 = .Name = "obj_name_1"
       .prop_A = "vlue_A1"
       .prop_B = "vlue_B1"

el_2 = .Name = "obj_name_2"
       .prop_A = "vlue_A2"
       .prop_B = "vlue_B2"

el_N = .Name = "obj_name_N"
       .prop_A = "vlue_AN"
       .prop_B = "vlue_BN"

I've tried several queries the best I got, but still not working, is the following:

Dim class_name_1_List = _
    From el In test...<Class> _
    Where el.@name = "class_name_1"
    Select New With {.Name = el...<Object>.@name, _
                     .prop_A = (From a In el...<Property> _
                                Where a.@name = "prop_A" _
                                Select a.Value), _
                     .prop_B = (From a In el...<Property> _
                                Where a.@name = "prop_B" _
                                Select a.Value)}

And what I get with that code is just one element (the first) with the name of the first element and the properties each with a list of all the selected property in the file.

Like this:

class_name_1_List.Count = 1
el(0) = .Name = "obj_name_1"
        .prop_A ={value_A1, value_A2, value_A3, ..., value_AN}
        .prop_B ={value_B1, value_B2, value_B3, ..., value_BN}

Does someone know where I'm wrong and how should be the correct query to get what I need?

UPDATE:

Keep trying I found a solution that I'd like to share. Anyway if somebody knows some different or more efficient ways to do this I'll appreciate any fix.

    Dim class_name_1_list = (From el In test...<Class> _
                          Where el.@name = "class_name_1" _
                          Select From o In el...<Object> _
                                 Select New With {.name = o.@name, _
                                                  .prop_A = (From a In o...<Property> _
                                                            Where a.@name = "prop_A" _
                                                            Select a.Value).First(), _
                                                  .prop_B = (From a In o...<Property> _
                                                            Where a.@name = "prop_B" _
                                                            Select a.Value).First()}).First()
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

0

I couldn't exactly figure out what structure you're after, so would be happy to alter this once you can provide some feedback.

First, if you don't have it already, I suggest you grab LinqPad and install it as a simple code scratchpad.

Then copy the following in there and hit F5. The Dump() command spits the variable out to the console.

The first variable xml uses a nice little multiline-string VB.NET trick I found here: Multiline strings in VB.NET

dim xml as String = <![CDATA[<?xml version='1.0' encoding='utf-8'?>
<ObjectPropertyModule Project='PROJECT NAME' xmlns:dt='urn:schemas-microsoft-com:datatypes'>
    <Classes>
        <Class name='class_name_1'>
            <Objects>
                <Object name='obj_name_1'>
                    <Properties>
                        <Property name='prop_A' dt:dt='string'>value_A1</Property>
                        <Property name='prop_B' dt:dt='string'>value_B1</Property>
                    </Properties>
                </Object>
                <Object name='obj_name_2'>
                    <Properties>
                        <Property name='prop_A' dt:dt='string'>value_A2</Property>
                        <Property name='prop_B' dt:dt='string'>value_B2</Property>
                    </Properties>
                </Object>
                <Object name='obj_name_3'>
                    <Properties>
                        <Property name='prop_A' dt:dt='string'>value_A3</Property>
                        <Property name='prop_B' dt:dt='string'>value_B3</Property>
                    </Properties>
                </Object>
                <Object name='obj_name_N'>
                    <Properties>
                        <Property name='prop_A' dt:dt='string'>value_AN</Property>
                        <Property name='prop_B' dt:dt='string'>value_BN</Property>
                    </Properties>
                </Object>
            </Objects>
        </Class>
        <Class name='class_name_2'>
            <Objects>...</Objects>
        </Class>
        <Class name='class_name_3'>
            <Objects>...</Objects>
        </Class>
    </Classes>
</ObjectPropertyModule>]]>.Value

dim doc as XDocument = XDocument.Parse(xml)
dim data =  From rowClass In doc.Root.Descendants("Class")
            Select New With {
                .Name = rowClass.Attribute("name").Value,
                .Data = From rowObject In rowClass.Descendants("Object")
                        Select New With {
                            .Name = rowObject.Attribute("name").Value,
                            .PropA = rowObject.Descendants("Property").First(Function(d) d.Attribute("name").Value = "prop_A").Value,
                            .PropB = rowObject.Descendants("Property").First(Function(d) d.Attribute("name").Value = "prop_B").Value
                        }
            }
data.Dump()

The output looks like this: Linqpad output

Community
  • 1
  • 1
atom.gregg
  • 987
  • 8
  • 14