VB - LINQ To XML:嵌套查询与复杂Xml文件中的anon类型

时间:2014-10-27 10:00:17

标签: xml vb.net linq

自从星期五以来,我一直在尝试和搜索解决方案,但是我遇到了一些问题。

我有一个像这样的xml文件:

<?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>

我需要一个包含这样的匿名对象的列表:

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"

我已经尝试了几次我最好的查询,但仍然无效,如下:

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)}

我得到的代码只是一个元素(第一个),第一个元素的名称和属性,每个属性都包含文件中所有选定属性的列表。

像这样:

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}

有人知道我哪里错了,应该如何才能获得我需要的正确查询?

更新

继续尝试我找到了一个我想分享的解决方案。无论如何,如果有人知道一些不同或更有效的方法,我会感激任何修复。

    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()

1 个答案:

答案 0 :(得分:0)

我无法确切地知道你所追求的结构,所以一旦你能提供一些反馈,我们很乐意改变这种结构。

首先,如果您还没有,我建议您抓住LinqPad并将其安装为简单的代码暂存器。

然后在那里复制以下内容并点击F5。 Dump()命令将变量吐出到控制台。

第一个变量xml使用了我在这里找到的一个很好的小多线字符串VB.NET技巧: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()

输出如下: Linqpad output