【问题标题】:LINQ to XML: how do I add child elements in a for-each loop?LINQ to XML:如何在 for-each 循环中添加子元素?
【发布时间】:2024-05-04 18:20:04
【问题描述】:
Dim names() As String = {"one", "two", "three"}
Dim xml As XElement = Nothing
For Each name In names
  If xml Is Nothing Then
    xml = New XElement(name)
  Else
    xml.Add(New XElement(name)
  End If
Next

上面的代码将创建如下内容:

  <One>
    <Two />
    <Three />
  </One>

我需要的是这样的:

  <One>
    <Two>
      <Three />
    </Two>
  </One>

我尝试使用 xml.Elements.Last.Add(New XElement(name)),但由于某种原因,Last 方法不一定会返回最后一个元素。

谢谢!

【问题讨论】:

    标签: .net xml linq-to-xml


    【解决方案1】:

    对您当前的代码稍作改动即可满足您的要求:

    Dim names() As String = {"one", "two", "three"}
    Dim xml As XElement = Nothing
    For Each name In names
      Dim new_elem As New XElement(name)
      If xml IsNot Nothing Then
          xml.Add(new_elem)
      End If
      xml = new_elem
    Next
    

    编辑:

    你可以引入另一个变量来存储根元素:

    Function BuildTree() As XElement
        Dim tree As XElement = Nothing
    
        Dim names() As String = {"one", "two", "three"}
        Dim xml As XElement = Nothing
        For Each name In names
            Dim new_elem As New XElement(name)
            If tree Is Nothing Then
                tree = new_elem
            Else
                xml.Add(new_elem)
            End If
            xml = new_elem
        Next
    
        Return tree
    End Function
    

    【讨论】:

    • 我相信这就是我想要的。如果这段代码在一个函数中,如果xml 最终引用最后一个子元素,我将如何返回我构建的整个树?
    • 请查看更新后的答案:只需将第一个创建的元素存储在不会被函数修改的变量中
    【解决方案2】:

    看起来你只是想add on an XElement -- 不要使用.Last 或其他任何东西,在最后一个之后添加是默认行为..

    IOW:

    你可以说:

    Dim node1 as XElement = new XElement( "A1")
    Dim node2 as XElement = new XElement( "A2")
    Dim node3 as XElement = new XElement ("A3")
    node2.Add( node3)
    Dim root as XElement = new XElement("Root",new XElement(){node1,node2})
    

    获得:

    <Root>
      <A1 />
      <A2>
        <A3 />
      </A2>
    </Root>
    

    或者做同样的事情:

    Dim node1 as XElement = new XElement( "A1")
    Dim node2 as XElement = new XElement( "A2")
    Dim node3 as XElement = new XElement ("A3")
    Dim root as XElement = new XElement("Root")
    Dim children as XElement() = new XElement(){node1,node2}
    for each child in children 
        root.add( child)
        if child.Name = "A2"
            child.Add( node3)
        end if
    next
    

    如果您正在寻找在树中开始的最后一个节点(上例中的 A3),您需要:

    root.Descendants().Last()
    

    这真的是你想要的吗(当问这个问题时,最好给出一棵树并说明你想要隔离哪些节点)?

    【讨论】:

      最近更新 更多