Imports System
Imports System.IO
Imports System.Xml
Namespace E
Public Class FilterReader
Inherits TextReader
Private Class FilterBuffer
Private tr As TextReader
Private faketag As String
Private startmarker As String
Private endmarker As String
Private line As String
Private ix As Integer
Private active As Boolean
Private done As Boolean
Public Sub New(tr As TextReader, faketag As String, startmarker As String, endmarker As String)
Me.tr = tr
Me.faketag = faketag
Me.startmarker = startmarker
Me.endmarker = endmarker
' fake start tag
line = "<" & faketag & ">"
ix = 0
active = False
done = False
End Sub
Private Function Fill() As Boolean
' more characters in current line
If ix < line.Length Then
Return True
End If
' already seen EOF
If done Then
Return False
End If
' get a new valid line
Do
line = tr.ReadLine()
' if EOF do fake end tag
If line Is Nothing Then
line = "</" & faketag & ">"
ix = 0
done = True
Return True
End If
' sort out garbage from valid XML
If active Then
Dim endix As Integer = line.IndexOf(endmarker)
If endix >= 0 Then
line = line.Substring(0, endix + endmarker.Length)
active = False
End If
Else
Dim startix As Integer = line.IndexOf(startmarker)
If startix >= 0 Then
line = line.Substring(startix)
active = True
Dim endix As Integer = line.IndexOf(endmarker)
If endix >= 0 Then
line = line.Substring(0, endix + endmarker.Length)
active = False
End If
Else
' will trigger new read
line = Nothing
End If
End If
Loop While line Is Nothing OrElse line.Length = 0
' we got a valid line
ix = 0
Return True
End Function
Public Function Read() As Integer
If Not Fill() Then
Return -1
End If
Dim c As Integer = AscW(line(ix))
ix += 1
Return c
End Function
Public Function ReadLine() As String
If Not Fill() Then
Return Nothing
End If
Dim s As String = line.Substring(ix)
ix = line.Length
Return s
End Function
End Class
Private buf As FilterBuffer
Public Sub New(real As TextReader, faketag As String, startmarker As String, endmarker As String)
Me.buf = New FilterBuffer(real, faketag, startmarker, endmarker)
End Sub
Public Overrides Function Read() As Integer
Return buf.Read()
End Function
Public Overrides Function ReadLine() As String
Return buf.ReadLine()
End Function
Public Overrides Function ReadToEnd() As String
Throw New Exception("ReadToEnd does not work")
End Function
End Class
Public Class Program
Public Shared Sub Main(args As String())
Dim xr As XmlReader = New XmlTextReader(New FilterReader(New StreamReader("C:\work\dirty.xml"), "fake", "<a>", "</a>"))
While xr.Read()
Console.WriteLine("type={0} name={1} value={2}", xr.NodeType, xr.Name, xr.Value)
End While
xr.Close()
Console.ReadKey()
End Sub
End Class
End Namespace
junk
<a>
<b>1</b>
<b>2</b>
</a>
junk
<a>
<b>3</b>
<b>4</b>
</a>
junk
junk <a></a>
<a></a> junk
junk <a></a> junk
type=Element name=fake value=
type=Element name=a value=
type=Element name=b value=
type=Text name= value=1
type=EndElement name=b value=
type=Element name=b value=
type=Text name= value=2
type=EndElement name=b value=
type=EndElement name=a value=
type=Element name=a value=
type=Element name=b value=
type=Text name= value=3
type=EndElement name=b value=
type=Element name=b value=
type=Text name= value=4
type=EndElement name=b value=
type=EndElement name=a value=
type=Element name=a value=
type=EndElement name=a value=
type=Element name=a value=
type=EndElement name=a value=
type=Element name=a value=
type=EndElement name=a value=
type=EndElement name=fake value=