Search code examples
vb.netwhile-loopstreamreader

Any way to force read next line while in StreamReader loop?


I'm working on a txt file and I was wondering if there was a way to force the streamreader to read the next line after I've used the value of the one it currently read.

My code:

Private Sub subTest()
    Dim sr As New StreamReader("d:\input\cleanedUp.txt")
    Dim doc As New XmlDocument
    Dim root As XmlElement = doc.CreateElement("Views")
    Dim ns As String = sr.ReadLine()
    Dim nsAtt As XmlAttribute = doc.CreateAttribute("ClientCode")
    nsAtt.Value = ns
    root.Attributes.Append(nsAtt)

    While Not sr.EndOfStream
        Dim sLine As String = sr.ReadLine

        doc.AppendChild(root)
        Dim child As XmlElement = doc.CreateElement("View")
        root.AppendChild(child)
        Dim newAtt As XmlAttribute = doc.CreateAttribute("Name")
        newAtt.Value = sLine
        child.Attributes.Append(newAtt)

        Dim subChild As XmlElement = doc.CreateElement("Criteria")
        child.AppendChild(subChild)
        subChild.InnerText = sLine
    End While
    sr.Close() : sr.Dispose()

    Dim sett As New XmlWriterSettings
    sett.Indent = True

    Dim sw As XmlWriter = XmlWriter.Create("d:\input\data.xml", sett)
    doc.Save(sw)
    sw.Flush() : sw.Close()
End Sub

Result is this:

<?xml version="1.0" encoding="utf-8"?>
<Views ClientCode="WSMCABS">
    <View Name="vACCESSONE">
        <Criteria>vACCESSONE</Criteria>
    </View>
    <View Name="ACCESSONE">
        <Criteria>ACCESSONE</Criteria>
    </View>
</Views>

What I want is this:

    <?xml version="1.0" encoding="utf-8"?>
<Views ClientCode="WSMCABS">
    <View Name="vACCESSONE">
        <Criteria>ACCESSONE</Criteria>
    </View>
    <View Name="vSample2">
        <Criteria>SAMPLE2</Criteria>
    </View>
</Views>

Solution

  • So the issue I was having was pretty much that the reader would create a new child/subchild for every line read, and instead I wanted a child with multiple subchilds. So it's a bit of a hack, but I was able to accomplish this by setting a loop with certain conditions that applied to my situation. This may not be the best answer for anyone else out there trying to accomplish something similar, but it worked for me since my text file was composed of SQL views that began with a "v" followed by the criteria for that particular view. The program then breaks out of adding additional subchild nodes when it sees that another view (starting with "v") is read on the line.

    While Not sr.EndOfStream
    
            doc.AppendChild(root)
            Dim child As XmlElement = doc.CreateElement("View")
            root.AppendChild(child)
            Dim newAtt As XmlAttribute = doc.CreateAttribute("Name")
            newAtt.Value = sLine
            child.Attributes.Append(newAtt)
    
            If sLine.StartsWith("v") Then
                sLine = sr.ReadLine
                While Not sLine.StartsWith("v")
                    Dim subChild As XmlElement = doc.CreateElement("Criteria")
                    child.AppendChild(subChild)
                    subChild.InnerText = sLine
                    sLine = sr.ReadLine
                    If sLine = Nothing Then
                        sLine = sr.ReadLine
                    End If
                    If sLine = Nothing Then
                        Exit While
                    End If
                End While
            End If
    
        End While
        sr.Close() : sr.Dispose()