I need to delete all nodes with a specific attribute value. Using XDocument.Descendants.Where clause with an inline function it's a snap to delete nodes based on a specific attribute value.
That works great.
I also need to delete all nodes that have specific descendant value. It made sense to me to use the same method for checking a descendant node of each element, and when that descendant value (innertext) matches a given value to look for, delete the element.
It almost works.
My code:
Dim Xmlstring As String =
"<?xml version=" & Chr(34) & "1.0" & Chr(34) & " encoding=" & Chr(34) & "UTF-8" & Chr(34) & "?>" & vbNewLine &
"<domain:DOGs " & vbNewLine &
" page=" & Chr(34) & "1" & Chr(34) & vbNewLine &
" ofPages=" & Chr(34) & "1" & Chr(34) & vbNewLine &
" xmlns:domain=" & Chr(34) & "urn:cat:np.domain.2111-14-42" & Chr(34) & vbNewLine &
" xmlns:vs=" & Chr(34) & "urn:cat:vs.2111-15-31" & Chr(34) & vbNewLine &
" xmlns:base=" & Chr(34) & "urn:cat:base.2111-15-31" & Chr(34) & ">" & vbNewLine &
" <domain:DOG name=" & Chr(34) & "Fido" & Chr(34) & ">" & vbNewLine &
" <description>Good</description>" & vbNewLine &
" </domain:DOG>" & vbNewLine &
" <domain:DOG name=" & Chr(34) & "Abby" & Chr(34) & ">" & vbNewLine &
" <description>Bad</description>" & vbNewLine &
" </domain:DOG>" & vbNewLine &
" <domain:DOG name=" & Chr(34) & Chr(34) & ">" & vbNewLine &
" <description>Ugly</description>" & vbNewLine &
" </domain:DOG>" & vbNewLine &
" <domain:DOG name=" & Chr(34) & "Bruno" & Chr(34) & ">" & vbNewLine &
" <description>Sweaty</description>" & vbNewLine &
" </domain:DOG>" & vbNewLine &
" <domain:DOG name=" & Chr(34) & "Shep" & Chr(34) & ">" & vbNewLine &
" <description>Good</description>" & vbNewLine &
" </domain:DOG>" & vbNewLine &
"</domain:DOGs>"
Dim Xdoc As XDocument = XDocument.Parse(Xmlstring)
Dim iFoundCount As Integer = 0
'This works:
With Xdoc.Descendants().Descendants()
iFoundCount = .Where(Function(e) e.Attributes("name").Any(Function(a) a = "")).Count
.Where(Function(e) e.Attributes("name").Any(Function(a) a = "")).Remove()
End With
Dim sResultFile As String = "c:\0\1st_result_" & iFoundCount.ToString & ".xml"
Xdoc.Save(sResultFile)
'The result:
'<?xml version="1.0" encoding="utf-8"?>
'<domain:DOGs page="1" ofPages="1" xmlns:domain="urn:cat:np.domain.2111-14-42" xmlns:vs="urn:cat:vs.2111-15-31" xmlns:base="urn:cat:base.2111-15-31">
' <domain:DOG name="Fido">
' <description>Good</description>
' </domain:DOG>
' <domain:DOG name="Abby">
' <description>Bad</description>
' </domain:DOG>
' <domain:DOG name="Bruno">
' <description>Sweaty</description>
' </domain:DOG>
' <domain:DOG name="Shep">
' <description>Good</description>
' </domain:DOG>
'</domain:DOGs>
'This looks like it would work as there aren't any errors in the code
'and it almost works.
Xdoc = Nothing
Xdoc = XDocument.Parse(My.Computer.FileSystem.ReadAllText(sResultFile))
iFoundCount = 0
With Xdoc.Descendants().Descendants()
iFoundCount = .Where(Function(e) e.Descendants("description").Value.Any(Function(a) a = "Sweaty")).Count '<-- error occurs here
.Where(Function(e) e.Descendants("description").Value.Any(Function(a) a = "Sweaty")).Remove()
End With
sResultFile = "c:\0\2nd_result_" & iFoundCount.ToString & ".xml"
Xdoc.Save(sResultFile)
I get a popup pointing to the 'iFoundCount =' line that reads
ArgumentNullException was unhandled
Value cannot be null.
Parameter name: source
What am I missing?
What do I do?