将Linq嵌套在XML文字中

时间:2015-12-04 05:43:44

标签: xml vb.net linq

使用三级层次结构(Person,Kid,Toy:一个人有一个或多个孩子,每个孩子有一个或多个玩具),如何使用XML Literals将其导出为XML?我使用以下代码(p是作为参数进入的Person对象):

Dim X = <Person Name=<%= p.Name %>>
  <%= From k In p.GetKids()
      Select <Kid Name=<%= k.Name %>>
      <%= From t In k.GetToys()
          Select <Toy Name=<%= k.Name %> <%= IIf(t.IsBatteryOperated(), "Batteries=""" & t.BatteriesCount & """, "") %> />
  </Kid>
</Person>

我在这里尝试了两件事。我试图将一个LINQ-2-XML嵌套在另一个LINQ-2-XML中。其次,我尝试添加只会出现在电池供电的Batteries节点中的可选属性<Toy>。但是这段代码没有编译,我无法弄清楚它有什么问题。有谁知道我怎么能纠正这个?

更新

行。我已经部分修复了它。以下作品:

<Person Name=<%= p.Name %>>
  <%= From k In p.GetKids()
      Select <Kid Name=<%= k.Name %>>
        <%= From t In k.GetToys()
            Select <Toy Percentage=<%= t.Name %> /> %>
      </Kid> %>
</Person>

上面的代码编译得很好,但是一旦我尝试添加可选属性,它就会再次开始抱怨。所以现在唯一的问题是以某种方式在<Toy>节点内添加以下表达式:

<%= IIf(t.IsBatteryOperated(), "Batteries=""" & t.BatteriesCount & """, "") %>

更新2

请参阅下面的答案。

3 个答案:

答案 0 :(得分:3)

最后在this SO post的帮助下计算出来。对于其他寻找它的人,你只需要在内部linq-2-xml调用中创建一个XElement直通投影:

<Person Name=<%= p.Name %>>
  <%= From k In p.GetKids()
      Select <Kid Name=<%= k.Name %>>
        <%= From t In k.GetToys()
            Select New XElement("Toy",
                       New XAttribute("Name", t.Name),
                       AttributeOrNull("Batteries", If(t.IsBatteryOperated(), Nothing, t.BatteriesCount))) %>
      </Kid> %>
</Person>

其中AttributeOrNull()是下面定义的辅助函数:

Public Shared Function AttributeOrNull(name As XName, value As String) As XAttribute
    Return If(String.IsNullOrEmpty(value), Nothing, New XAttribute(name, value))
End Function

更新

为了完整起见,请查看Jeff的答案如下。通过使用声明性语法,可以使上述代码更小/更好,如他的回答中所述。

答案 1 :(得分:1)

您可以通过这种方式获得更好的语法:

<Person Name=<%= p.Name %>>
  <%= From k In p.GetKids
      Select
        <Kid Name=<%= k.Name %>>
          <%= From t In k.GetToys
              Select 
                <Toy
                  Percentage=<%= t.Name %>
                  <%= If(t.IsBatteryOperated, New XAttribute("Batteries", t.BatteriesCount), Nothing) %>
                />
          %>
        </Kid>
  %>
</Person>

答案 2 :(得分:0)

我的意见,您的编码问题是由未经过深思熟虑的XML结构引起的。 基本材料应该放在元素中。在我看来,所有数据都是必不可少的。如果采用看起来更像这样的结构,

<parents>
    <parent>
        <pname></pname>
        <kids>
            <kid>
                <kname></kname>
                <toys>
                    <toy>
                        <tname></tname>
                        <batteries>
                            <type>
                                <count></count>
                            </type>
                        </batteries>
                    </toy>
                </toys>
            </kid>
        </kids>
    </parent>
</parents>

您的编码问题变得更简单,XML更清晰。如果电池元件为空或计数为零,则玩具不需要电池。

示例:

<parents>
    <parent>
        <pname>Joe Parent</pname>
        <kids>
            <kid>
                <kname>Sally</kname>
                <toys>
                    <toy>
                        <tname>Remote Contolled Car</tname>
                        <batteries>
                            <type>D
                                <count>2</count>
                            </type>
                            <type>AA
                                <count>4</count>
                            </type>
                        </batteries>
                    </toy>
                </toys>
            </kid>
            <kid>
                <kname>Sam</kname>
                <toys>
                    <toy>
                        <tname>Teddy Bear</tname>
                        <batteries>
                            <type>none
                                <count>0</count>
                            </type>
                        </batteries>
                    </toy>
                </toys>
            </kid>
        </kids>
    </parent>
</parents>

我有一个基于XML的系统,有80多种不同类型的标签。只有其中一个属性定义了一个属性,我仍然质疑它是否应该是一个标记。