Results 1 to 2 of 2

Thread: Simple XML Parser

  1. #1

    Thread Starter
    Addicted Member NinjaNic's Avatar
    Join Date
    Dec 2013
    Location
    Earth
    Posts
    230

    Simple XML Parser

    Hi all!

    Here's a simple XML parser written with pure VB. The code can be found below. (You might ask why I did this. Do I need to have a reason?)

    How it works is that every <tag></tag> is created as a class called XMLToken. An XMLToken has 4 properties: name, attributes, value, and a list of child tokens/subtokens. An XMLToken cannot (should not) have both a value property and a child tokens property.

    vb Code:
    1. Option Strict On
    2. Option Explicit On
    3.  
    4. Namespace XML
    5.  
    6.     ''' <summary>
    7.     ''' Represents an entire XML document.
    8.     ''' </summary>
    9.     Class XMLDoc
    10.         Inherits XMLToken
    11.  
    12.         ''' <summary>
    13.         ''' Creates a blank XML document.
    14.         ''' </summary>
    15.         Sub New()
    16.             MyBase.New("XML", "")
    17.         End Sub
    18.  
    19.         ''' <summary>
    20.         ''' Creates and automatically parses an XML document from an existing string.
    21.         ''' </summary>
    22.         ''' <param name="XMLString">Existing XML String</param>
    23.         Sub New(XMLString As String)
    24.             MyBase.New("XML", XMLString)
    25.         End Sub
    26.  
    27.         ''' <summary>
    28.         ''' Writes this element as a string.
    29.         ''' </summary>
    30.         Public Overrides Function ToString() As String
    31.             Dim TempVal As String = ""
    32.             For i As Int32 = 0 To Tokens.Count - 1 Step 1
    33.                 TempVal &= Tokens(i).ToString & vbNewLine
    34.             Next
    35.             Return TempVal
    36.         End Function
    37.  
    38.     End Class
    39.  
    40.     ''' <summary>
    41.     ''' Represents an XML Token with 4 properties: Name, Attributes, Value, and Child Tokens. Note: A token cannot have both a value and child tokens property.
    42.     ''' </summary>
    43.     Class XMLToken
    44.  
    45.         ''' <summary>
    46.         ''' The name (tag) of the token.
    47.         ''' </summary>
    48.         Property Name As String
    49.         ''' <summary>
    50.         ''' The attributes associated with the element, may be blank.
    51.         ''' </summary>
    52.         Property Attributes As String
    53.         ''' <summary>
    54.         ''' The value of the token.
    55.         ''' </summary>
    56.         Property Value As String
    57.         ''' <summary>
    58.         ''' A list of child tokens.
    59.         ''' </summary>
    60.         Property Tokens As List(Of XMLToken)
    61.  
    62.         ''' <summary>
    63.         ''' Programatically creates a new XMLToken.
    64.         ''' </summary>
    65.         ''' <param name="Name_New">Name (tag) Property</param>
    66.         ''' <param name="Value_New">Value Property (Can be written in XML, automatically parsed)</param>
    67.         Sub New(Name_New As String, Value_New As String)
    68.             Name = Name_New
    69.             Attributes = ""
    70.             Value = Value_New
    71.             Tokens = New List(Of XMLToken)
    72.             Search(Value.Trim)
    73.         End Sub
    74.  
    75.         ''' <summary>
    76.         ''' Manually creates a new XMLToken.
    77.         ''' </summary>
    78.         ''' <param name="Name_New">Name (tag) Property</param>
    79.         ''' <param name="Children">The child tokens as a list.</param>
    80.         Sub New(Name_New As String, Children As List(Of XMLToken))
    81.             Name = Name_New
    82.             Attributes = ""
    83.             Value = ""
    84.             Tokens = New List(Of XMLToken)(Children)
    85.         End Sub
    86.  
    87.         ''' <summary>
    88.         ''' Programatically creates a new XMLToken.
    89.         ''' </summary>
    90.         ''' <param name="Name_New">Name (tag) Property</param>
    91.         ''' <param name="Attributes_New">Attributes Property (written="like this")</param>
    92.         ''' <param name="Value_New">Value Property (Can be written in XML, automatically parsed)</param>
    93.         Sub New(Name_New As String, Attributes_New As String, Value_New As String)
    94.             Name = Name_New
    95.             Attributes = Attributes_New.Trim
    96.             Value = Value_New
    97.             Tokens = New List(Of XMLToken)
    98.             Search(Value.Trim)
    99.         End Sub
    100.  
    101.         ''' <summary>
    102.         ''' Manually creates a new XMLToken.
    103.         ''' </summary>
    104.         ''' <param name="Name_New">Name (tag) Property</param>
    105.         ''' <param name="Attributes_New">Attributes Property (written="like this")</param>
    106.         ''' <param name="Children">The child tokens as a list.</param>
    107.         Sub New(Name_New As String, Attributes_New As String, Children As List(Of XMLToken))
    108.             Name = Name_New
    109.             Attributes = Attributes_New.Trim
    110.             Value = ""
    111.             Tokens = New List(Of XMLToken)(Children)
    112.         End Sub
    113.  
    114.         ''' <summary>
    115.         ''' A somewhat recursive function that creates new tokens and child tokens.
    116.         ''' </summary>
    117.         ''' <param name="TokenString">The string to search for tokens, usually the parent token's value.</param>
    118.         Private Sub Search(TokenString As String)
    119.             Dim Another As Boolean = False
    120.             For i As Int32 = 0 To TokenString.Count - "<_></_>".Length Step 1
    121.                 If TokenString(i) = "<"c Then
    122.                     i += 1
    123.                     Dim NameEnd As Int32 = -1
    124.                     For j As Int32 = i + 1 To TokenString.Count - "></_>".Length Step 1
    125.                         If (TokenString(j) = " "c OrElse TokenString(j) = ">"c) AndAlso NameEnd = -1 Then NameEnd = j
    126.                         If TokenString(j) = ">"c Then
    127.                             Dim TokenName As String = TokenString.Substring(i, NameEnd - i)
    128.                             Dim TokenAttr As String = TokenString.Substring(NameEnd, j - NameEnd)
    129.                             Dim TokenEnd As String = $"</{TokenName}>"
    130.                             j += 1
    131.                             For k As Int32 = j To TokenString.Length - TokenEnd.Length
    132.                                 If TokenString.Substring(k, TokenEnd.Length) = TokenEnd Then
    133.                                     Dim TokenValue As String = TokenString.Substring(j, k - j)
    134.                                     Tokens.Add(New XMLToken(TokenName, TokenAttr, TokenValue)) ' SUCCESS!
    135.                                     i = k + TokenEnd.Length
    136.                                     If i >= TokenString.Count Then Exit Sub
    137.                                     Another = True
    138.                                     Exit For
    139.                                 End If
    140.                             Next
    141.                             If Another Then Exit For
    142.                         End If
    143.                     Next
    144.                     Another = False
    145.                 End If
    146.             Next
    147.         End Sub
    148.  
    149.         ''' <summary>
    150.         ''' Retrieves all the child tokens with a specific name.
    151.         ''' </summary>
    152.         ''' <param name="TokenName">The name of the token.</param>
    153.         Function GetToken(TokenName As String) As List(Of XMLToken)
    154.             Dim L As New List(Of XMLToken)
    155.             For i As Int32 = 0 To Tokens.Count - 1 Step 1
    156.                 If Tokens(i).Name = TokenName Then L.Add(Tokens(i))
    157.             Next
    158.             Return L
    159.         End Function
    160.  
    161.         ''' <summary>
    162.         ''' Writes this element as a string.
    163.         ''' </summary>
    164.         Public Overrides Function ToString() As String
    165.             If Tokens.Count > 0 Then
    166.                 Dim TempVal As String = vbNewLine
    167.                 For i As Int32 = 0 To Tokens.Count - 1 Step 1
    168.                     TempVal &= Tokens(i).ToString & vbNewLine
    169.                 Next
    170.                 Return $"<{Name}{If(Attributes.Length > 0, " ", "")}{Attributes}>{TempVal}</{Name}>"
    171.             End If
    172.             Return $"<{Name}{If(Attributes.Length > 0, " ", "")}{Attributes}>{Value}</{Name}>"
    173.         End Function
    174.  
    175.     End Class
    176.  
    177. End Namespace

    In the next post, I will demonstrate how to retrieve XML information using this tool. I will also show how to create XML documents from a "tree" of XMLTokens.

  2. #2

    Thread Starter
    Addicted Member NinjaNic's Avatar
    Join Date
    Dec 2013
    Location
    Earth
    Posts
    230

    Re: Simple XML Parser

    Take this file, for instance:

    xml Code:
    1. <class type="identifier">
    2.     <demo>Hello World!</demo>
    3.     <demo>What kind of music do you like?</demo>
    4. </class>

    This commented code shows how to retrieve specific information for use:

    vb Code:
    1. ' Creates a new XML document from a text file.
    2. Dim D As New XMLDoc(IO.File.ReadAllText("C:\Path\test.xml"))
    3.  
    4. Console.WriteLine(D.ToString) ' Prints the entire document.
    5.  
    6. ' Gets the first instance of <class> and then the first instance of <demo> in it.
    7. Console.WriteLine(D.GetToken("class")(0).GetToken("demo")(0).Value)
    8. ' Output: Hello World!
    9.  
    10. ' The same thing can be written many different ways.
    11. Console.WriteLine(D.Tokens(0).Tokens(0).Value)
    12. ' Output: Hello World!
    13.  
    14. ' Calling .ToString() instead of .Value will show the XML tags.
    15. Console.WriteLine(D.Tokens(0).Tokens(0).ToString)
    16. ' Output: <demo>Hello World!</demo>

    If you wanted to create that XML from scratch:

    vb Code:
    1. ' Creates a blank document.
    2. Dim D As New XMLDoc()
    3.  
    4. ' Adds a new base token to the document.
    5. D.Tokens.Add(New XMLToken("class", "type=""identifier""", New List(Of XMLToken)))
    6.  
    7. ' Creates the subtokens.
    8. D.GetToken("class")(0).Tokens.Add(New XMLToken("demo", "Hello World!"))
    9. D.GetToken("class")(0).Tokens.Add(New XMLToken("demo", "What kind of music do you like?"))
    10.  
    11. ' Make sure everything is correct.
    12. Console.WriteLine(D.ToString)

    Output: (Note that it will not tab any lines, but this does not affect the code.)

    xml Code:
    1. <class type="identifier">
    2. <demo>Hello World!</demo>
    3. <demo>What kind of music do you like?</demo>
    4. </class>

    Incidentally, using both of this knowledge, you can modify a pre-existing XML doument. (Both of this knowledge? That doesn't sound right. Both of these knowledges?)

    vb Code:
    1. ' Creates a new XML document from a text file.
    2. Dim D As New XMLDoc(IO.File.ReadAllText("C:\Path\test.xml"))
    3.  
    4. ' Adds a new element under the class token.
    5. D.GetToken("class")(0).Tokens.Add(New XMLToken("demo", "I prefer classic rock."))
    6.  
    7. ' Saves the file.
    8. IO.File.WriteAllText("C:\Path\test.xml", D.ToString)

    Output:

    xml Code:
    1. <class type="identifier">
    2. <demo>Hello World!</demo>
    3. <demo>What kind of music do you like?</demo>
    4. <demo>I prefer classic rock.</demo>
    5. </class>

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width