Linq to XML Синтаксическая проблема «Где не в» - PullRequest
0 голосов
/ 21 октября 2008

Следующий код не компилируется

Dim BasicGroups As String() = New String() {"Node1", "Node2"}
Dim NodesToRemove = From Element In SchemaDoc.Root.<Group> _
                    Where Element.@Name not in BasicGroups
For Each XNode In NodesToRemove
    XNode.Remove()
Next

Предполагается удалить любого непосредственного потомка корневого узла, у которого есть атрибут с именем name, значение которого Не , указанное в BasicGroups StringArray.

Какой правильный синтаксис для этой задачи?

Ответы [ 4 ]

3 голосов
/ 21 октября 2008

Вы, вероятно, хотите переместить часть «не». Например (псевдо-код)

where (not (list.Contains(foo))
1 голос
/ 21 октября 2008

Если атрибут Name удаляемых узлов можно сопоставить с помощью простого шаблона, должно работать следующее:

Dim SchemaDoc As New XDocument(<Root><Group Name="Foo"/><Group Name="Node1"/>
                           <Group Name="Node2"/><Group name="Bar"/></Root>)
Dim NodesToRemove = From Element In SchemaDoc.<Root>.<Group> Where _
                           Element.@Name Like "NotNode?"
For Each XNode In NodesToRemove.ToArray()
  XNode.Remove()
Next

Обратите внимание на использование ToArray () в перечислении NodesToRemove: это понадобится вам для принудительной оценки XQuery перед началом изменения коллекции, на которой он основан.

Если это не сработает, вот альтернатива использованию LINQ (как изначально я думал, что вставка 'not' в запросы LINQ не будет работать, но я был прямо поставлен другим ответом - вы узнаете что-то новое каждый день ...):

Dim NodesToRemove As New Collections.ObjectModel.Collection(Of XNode)
For Each Element In SchemaDoc.<Root>.<Group>
  If Not BasicGroups.Contains(Element.@Name) Then
    NodesToRemove.Add(Element)
  End If
Next

Производительность должна быть в значительной степени идентична использованию LINQ.

0 голосов
/ 30 июля 2009
Dim NodesToRemove = From Element In SchemaDoc.Root.<Group> _
                    Where Not BasicGroups.Contains(Element.@Name)
0 голосов
/ 30 июля 2009

Может быть, вы можете попробовать что-то вроде этого

mylistWithOutUndesirebleNodes = (из b в NodeLists.Cast () где (из c в NodesToDeleteList.Cast () где c.Attributes ["атрибут"]. Значение == b.Attributes ["атрибут"]. значение выберите c) .Count () == 0 выберите b) .ToList ();

...