こんどは.NETのSystem.Xml.XmlReaderを使ってVisual Basicでやってみます.プログラムは以下のようなものです.(あいかわらずエラー処理は全然やってありません.)
Imports System.IO
Imports System.Xml
Module Main
Sub Main()
Dim xr = CreateXmlReader("MusicLibrary.xml")
Dim sw As StreamWriter = CreateStreamWiter("MusicLibrary_Copy.xml")
XmlCopy(xr, sw)
sw.Close()
End Sub
Function CreateStreamWiter(ByVal outputPath As String) As StreamWriter
Dim sw As StreamWriter = New StreamWriter(outputPath, False, System.Text.Encoding.GetEncoding("UTF-8"))
Return sw
End Function
Function CreateXmlReader(ByVal inputPath As String) As XmlReader
Dim rs As XmlReaderSettings = New XmlReaderSettings
rs.IgnoreProcessingInstructions = True
rs.IgnoreComments = True
rs.ConformanceLevel = ConformanceLevel.Document
Dim xr As XmlReader = XmlReader.Create(inputPath, rs)
Return xr
End Function
Sub XmlCopy(xr As XmlReader, sw As StreamWriter)
While xr.Read
Select Case xr.NodeType
Case XmlNodeType.Element
Dim elementName As String = xr.Name
Dim attributes As List(Of Attribute) = New List(Of Attribute)
While xr.MoveToNextAttribute
Dim attr As New Attribute
attr.setAttr(xr.Name, xr.ReadContentAsString)
attributes.Add(attr)
End While
StartElement(sw, elementName, attributes)
Case XmlNodeType.EndElement
Dim elementName As String = xr.Name
EndElement(sw, elementName)
Case XmlNodeType.Text
Dim text As String = xr.Value
OutText(sw, text)
Case XmlNodeType.Whitespace
Dim text As String = xr.Value
OutText(sw, text)
End Select
End While
End Sub
Structure Attribute
Dim name As String
Dim value As String
Sub setAttr(name As String, value As String)
Me.name = name
End Sub
End Structure
Sub StartElement(sw As StreamWriter, elementName As String, ByVal attributes As List(Of Attribute))
sw.Write("<" + elementName)
For Each attribute As Attribute In attributes
sw.Write(" " + attribute.name + "=""" + attribute.value + """")
Next
sw.Write(">")
End Sub
Sub EndElement(sw As StreamWriter, elementName As String)
sw.Write("</" + elementName + ">")
End Sub
Sub OutText(sw As StreamWriter, text As String)
sw.Write(text)
End Sub
End Module
コンテンツを取り出したら、そのノードタイプを判定して、Javaの場合と同じような処理を行います.
1.要素の始まりでは"<"+要素名+属性値+">"をPrintStreamに書き出します.
2.要素間のテキストはそのまま内容をPrintStreamに書き出します.
3.要素の終了では"</"+要素名+">"をPrintStreamに書き出します.
属性を記憶するために、
Structure Attribute
Dim name As String
Dim value As String
Sub setAttr(name As String, value As String)
Me.name = name
End Sub
End Structure
という構造体を定義して、
Dim attributes As List(Of Attribute) = New List(Of Attribute)
というリストに記憶しています.
プログラム構造からわかりますが、
1.PULL型なのでプログラムの側でコンテンツの読み出しを制御することができます.
2.しかしあくまでもイベント処理です.SAXと同じでReadメソッドで取得したコンテンツはその時点で処理できなければ、自分で記憶する必要があります.