Reputation: 3453
I have a XML xElement like:
<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>
In order to get rid of Trick nodes where value is null, I wrote:
myXmlElement.<Play>.<Trick>.Where(Function(m) m.<Trick>.Value = "").Remove()
Which works very well... Actually it works far too well, since ALL trick nodes are removed!
What do I do wrong? Is there a simpler way to proceed, without lambda expression?
Upvotes: 2
Views: 1707
Reputation: 134591
To see if the element is empty, you can inspect its child nodes through the Nodes()
method to see if it has anything. Filter by the empty nodes then remove them.
Note that in general, merely checking if the value is empty is wrong since there may be empty child elements.
''# assuming we have an XDocument with the above XML
myXmlDoc.<Play>.<Trick>.Where(Function(e) Not e.Nodes.Any).Remove()
Seeing as you wanted to do this using query notation (which by the way makes no difference):
Dim query = From e In myXmlDoc.<Play>.<Trick>
Where Not e.Nodes.Any
Select e
query.Remove()
Upvotes: 0
Reputation: 7076
You should use the == operator or .Equals() method.
myXmlElement.<Play>.<Trick>.Where(Function(m) m.<Trick>.Value == "").Remove()
or
myXmlElement.<Play>.<Trick>.Where(Function(m) m.<Trick>.Value.Equals(string.Empty)).Remove()
Upvotes: 0
Reputation: 3453
I have try the various solutions, none of them works! One only removes the 1st found node, the other one crashes at runtime...
Finally I came up with a simpler Visual Basic Linq - NO LAMBDA - solution, like this:
Dim xTricks = From x In myXmlElement.<Play>.<Trick> Where x.Value = "" Select x
xTricks.Remove()
Which I tested and which works fine...
Strange how complex solutions makes c# programers feel happyer!!!
Upvotes: 0
Reputation: 96557
Is that your complete XML element or a portion of it? It seems to be part of a larger element since I couldn't reproduce your results with just that portion.
If it's part of a larger piece of XML, use this approach:
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()
Notice that the XML is wrapped in <root>
nodes and the <Trick>
reference has been omitted from the Where
method.
If the XML is as you presented it, use this approach:
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)
In the above sample, notice that <Play>
has been omitted since it is the root of xml
, and that <Trick>
is also omitted from the Where
method.
Upvotes: 2