0

Below find xml sample and code i am using. When i was using with WhiteSpacehandling = None then out from 4 books records i was receiving only 2 (every second book). Solution i found was to use WhiteSpaceHandling set to WhiteSpacehandling = All - then i get 4 records because at the end of each line in xml is placed CR (carriage return) therefore reader is using it somehow to correctly take all the data from xml when parameter set to WhiteSpacehandling = All. Unfortunetly there is still problem when XML file data would be all in one line then even setting up WhitespaceHandling to All will not help and i would retreive every second book data (because no CR). Do you know how can i handle that problem? How to take always all data even if data is placed in one line?

XML file:

 <bookstore>
     <book genre="autobiography">
       <title>Potop</title>
       <author>
         <first-name>Benjamin</first-name>
         <last-name>Franklin</last-name>
       </author>
       <price>8.99</price>
     </book>
     <book genre="novel">
       <title>Faraon</title>
       <author>
         <first-name>Herman</first-name>
         <last-name>Melville</last-name>
       </author>
       <price>11.99</price>
     </book>
     <book genre="philosophy">
       <title>Ben Hur</title>
       <author>
         <name>Plato</name>
       </author>
       <price>9.99</price>
     </book>
     <book genre="scifi">
       <title>Terminator1</title>
       <author>
         <name>Plato</name>
       </author>
       <price>9.99</price>
     </book>
   </bookstore>

Code i am using:

 'Create the XML Reader
        Dim reader = New XmlTextReader("books.xml")

        reader.WhitespaceHandling = WhitespaceHandling.All  'WhitespaceHandling.None   '<----------


        Do While (reader.Read())
             If reader.IsStartElement And reader.NodeType = XmlNodeType.Element And reader.Name = "book" Then
            Console.WriteLine(reader.ReadOuterXml)
        End If
            End If

        Loop

Picture 1:

enter image description here

Picture 2:

enter image description here

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Arie
  • 3,041
  • 7
  • 32
  • 63
  • The whole point of relying on XMLReader is understanding the XML structure as such (not as text). What you are complaining about has just to do with treating the inputs as plain text (i.e., by ignoring the blank spaces in the input file or not). You should focus on extracting the XML information (e.g., genre, title, author, etc. of the given book node), rather than printing out the whole variable as text what is not too relevant here. In summary: don't worry about the blank spaces in the XML file, as far as the XML information will be parsed correctly anyway. – varocarbas Aug 24 '15 at 12:47
  • PS: you should rely on "Using" when reading a file (or alternatively perform the corresponding disposal actions). – varocarbas Aug 24 '15 at 12:50
  • You original code error has nothing to do with whitespaces!! It is your code logic that is skiing every other book record. Fix the code instead of implementing a kludge that give bad results. – jdweng Aug 24 '15 at 13:55
  • @jdweng - can you show how the fix should look like, any example? – Arie Aug 24 '15 at 15:13

2 Answers2

1

Try this

Imports System.IO
Imports System.Xml
Module Module1

    Sub Main()
        Dim input As String = _
        "<bookstore>" & _
     "<book genre=""autobiography"">" & _
       "<title>Potop</title>" & _
       "<author>" & _
         "<first-name>Benjamin</first-name>" & _
         "<last-name>Franklin</last-name>" & _
       "</author>" & _
       "<price>8.99</price>" & _
     "</book>" & _
     "<book genre=""novel"">" & _
       "<title>Faraon</title>" & _
       "<author>" & _
         "<first-name>Herman</first-name>" & _
         "<last-name>Melville</last-name>" & _
       "</author>" & _
       "<price>11.99</price>" & _
     "</book>" & _
     "<book genre=""philosophy"">" & _
       "<title>Ben Hur</title>" & _
       "<author>" & _
         "<name>Plato</name>" & _
       "</author>" & _
       "<price>9.99</price>" & _
     "</book>" & _
     "<book genre=""scifi"">" & _
       "<title>Terminator1</title>" & _
       "<author>" & _
         "<name>Plato</name>" & _
       "</author>" & _
       "<price>9.99</price>" & _
     "</book>" & _
   "</bookstore>"

        'Create the XML Reader
        Dim sReaader As New StringReader(input)
        Dim reader = New XmlTextReader(sReaader)


        reader.ReadToFollowing("book")
        Do While Not reader.EOF
            Dim line As String = reader.ReadOuterXml
            Console.WriteLine(line)

        Loop

    End Sub

End Module
​
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Don't use StringReader, use XMLTextReader like your original code. – jdweng Aug 24 '15 at 19:44
  • i meant XMLReader some people says its more recent than xmltextreader, what do you think - check my own answer i am showing it there... – Arie Aug 25 '15 at 07:59
  • I've been reading file for over 40 years. Started with Fortran, Pascal, standard C. I'm very good at parsing text files (including XML). I don't like any Microsoft I/O methods. The libraries are inconsistent and the methods don't always leave the current file pointer in the correct location to continue reading. You original method demonstates this issue. You were using Read to test for end of file which moved the file pointer. Then you used ReadOuterXML which also moved the pointer. The Read moved past the book tag so you got every other book tag. – jdweng Aug 25 '15 at 11:18
0

This one will solve the problem - in this case i can manually control line move, and this was the case therefore every second row was skipping.

 Using reader As XmlReader = XmlReader.Create("mybooks.xml")

                Do While Not reader.EOF
                    If reader.NodeType = XmlNodeType.Element And reader.Name = "book" And reader.IsStartElement Then


                        Dim line As String = reader.ReadOuterXml
                        Console.WriteLine(line)
                    Else
                        reader.Read()
                    End If
                Loop
            End Using
Arie
  • 3,041
  • 7
  • 32
  • 63