#.net #xml #vb.net #linq #linq-to-xml
#.net #xml #vb.net #linq #linq-to-xml
Вопрос:
У меня есть XML XElement, подобный:
<Play>
<Trick Lead="E" Win="S" TNum="1">S3.S2.S4.SA></Trick>
<Trick Lead="S" Win="N" TNum="2">DK.DA.D6.DQ></Trick>
..../...
<Trick Lead="" Win="" TNum="7"></Trick>
.../...
<Trick Lead="" Win="" TNum="13"></Trick>
</Play>
Для того, чтобы избавиться от хитрых узлов, где значение равно нулю, я написал:
myXmlElement.<Play>.<Trick>.Where(Function(m) m.<Trick>.Value = "").Remove()
Который работает очень хорошо… На самом деле это работает слишком хорошо, поскольку ВСЕ узлы трюков удалены!
Что я делаю не так? Есть ли более простой способ продолжить, без лямбда-выражения?
Комментарии:
1. Я никогда не видел
linq
, но мне как бы интересно узнать об этой части:Value = ""
? . Разве вы не должны сравнивать это с""
, а не устанавливать на""
? Я бы попробовал использовать это:Value == ""
(Я почти уверен, что ошибаюсь).2. В Visual Basic нет «==», но, возможно, есть «.Equals»… Я попробую, если ответа не будет. Кроме того, если вы никогда не видели Linq, зачем отвечать на вопрос Linq? LOL. кроме того: вы должны попробовать, Linq потрясающий!
3. Visual Basic на самом деле сохраняет мои нейроны в здравом уме 🙂
Ответ №1:
Это ваш полный XML-элемент или его часть? Похоже, это часть большего элемента, поскольку я не смог воспроизвести ваши результаты только с этой частью.
Если это часть большего фрагмента XML, используйте этот подход:
Dim xml = <root><Play>
<Trick Lead="E" Win="S" TNum="1">S3.S2.S4.SA></Trick>
<Trick Lead="S" Win="N" TNum="2">DK.DA.D6.DQ></Trick>
<Trick Lead="" Win="" TNum="7"></Trick>
<Trick Lead="" Win="" TNum="13"></Trick>
</Play></root>
xml.<Play>.<Trick>.Where(Function(m) m.Value = "").Remove()
Обратите внимание, что XML заключен в <root>
узлы, а <Trick>
ссылка была опущена из Where
метода.
Если XML такой, как вы его представили, используйте этот подход:
Dim xml = <Play>
<Trick Lead="E" Win="S" TNum="1">S3.S2.S4.SA></Trick>
<Trick Lead="S" Win="N" TNum="2">DK.DA.D6.DQ></Trick>
<Trick Lead="" Win="" TNum="7"></Trick>
<Trick Lead="" Win="" TNum="13"></Trick>
</Play>
xml.<Trick>.Where(Function(m) m.Value = "").Remove()
Console.WriteLine(xml)
В приведенном выше примере обратите внимание, что <Play>
это было опущено, поскольку это корень xml
, и это <Trick>
также исключено из Where
метода.
Ответ №2:
Я пробовал различные решения, ни одно из них не работает! Один удаляет только 1-й найденный узел, другой выходит из строя во время выполнения…
Наконец, я придумал более простое Visual Basic Linq — БЕЗ ЛЯМБДА-решения, например:
Dim xTricks = From x In myXmlElement.<Play>.<Trick> Where x.Value = "" Select x
xTricks.Remove()
Который я тестировал и который отлично работает…
Странно, насколько сложные решения радуют программистов c #!!!
Ответ №3:
Вы должны использовать оператор == или метод .Equals().
myXmlElement.<Play>.<Trick>.Where(Function(m) m.<Trick>.Value == "").Remove()
или
myXmlElement.<Play>.<Trick>.Where(Function(m) m.<Trick>.Value.Equals(string.Empty)).Remove()
Ответ №4:
Чтобы увидеть, пуст ли элемент, вы можете проверить его дочерние узлы с помощью Nodes()
метода, чтобы увидеть, есть ли в нем что-нибудь. Фильтруйте по пустым узлам, затем удалите их.
Обратите внимание, что в общем случае просто проверять, является ли значение пустым, неправильно, поскольку могут быть пустые дочерние элементы.
''# assuming we have an XDocument with the above XML
myXmlDoc.<Play>.<Trick>.Where(Function(e) Not e.Nodes.Any).Remove()
Поскольку вы хотели сделать это с использованием обозначения запроса (что, кстати, не имеет значения):
Dim query = From e In myXmlDoc.<Play>.<Trick>
Where Not e.Nodes.Any
Select e
query.Remove()