0

I'm making in VB.NET app, my Form have textboxes: txtName, txtLName, txtAge.

I need to enter multiple times this 3 variables(Name,LName,Age) and make XML file.

I use this code:

Dim settings As New XmlWriterSettings()
        settings.Indent = True

        ' Initialize the XmlWriter.
        Dim XmlWrt As XmlWriter = XmlWriter.Create("Test1.xml", settings)

        With XmlWrt

            ' Write the Xml declaration.
            .WriteStartDocument()


            ' Write the root element.
            .WriteStartElement("Invoice")

            ' Start our first person.
            .WriteStartElement("Person")

            ' The person nodes.

            .WriteStartElement("Name")
            .WriteString(txtName.Text.ToString())
            .WriteEndElement()

            .WriteStartElement("LName")
            .WriteString(txtLName.Text.ToString())
            .WriteEndElement()

            .WriteStartElement("Age")
            .WriteString(txtAge.Text.ToString())
            .WriteEndElement()

            ' The end of this person.
            .WriteEndElement()

            ' Close the XmlTextWriter.
            .WriteEndDocument()
            .Close()

        End With

        MessageBox.Show("XML file saved.")

But with this code I only got XML for one person.

I need one XML with more people. For example like this I need:

<?xml version="1.0" encoding="utf-8"?>
<Invoice>
  <Person>
    <Name>Pero</Name>
    <LName>Zder</LName>
    <Age>23</Age>
  </Person>
  <Person>
    <Name>Pero</Name>
    <LName>Zder</LName>
    <Age>23</Age>
  </Person>
  <Person>
    <Name>Pero</Name>
    <LName>Zder</LName>
    <Age>23</Age>
  </Person>
</Invoice>

edit: More info how app should work: I have 3 textboxes (txtName, txtLName, txtAge) and when I fill textboxes and click Next, after click textboxes cleared and I start filling new person. When I enter 20 persons I want to click export to XML, and got all 20 persons in XML file. Number of entries is changeable

Edit:

<?xml version="1.0" encoding="utf-8"?>
<Invoice>
  <Person>
    <Name>Pero</Name>
    <LName>Zder</LName>
    <Age>23</Age>
    <TEST>
       <Job>Yes</Job>
    </TEST>
  </Person>
</Invoice>

EDIT: My Code from APP:

Imports System.IO
Imports System.Xml
Imports System.Xml.Serialization
Imports XML_PisacTest

Public Class Form1

    Dim faktura As New Faktura

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        faktura.Ustanova.Add(New Ustanova() With {.Age = txtIsp.Text, .LName = txtFil.Text, .Name = txtName.Text})
        txtName.Text = ""
        txtLName.Text = ""
        txtAge.Text = ""

    End Sub


    Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click


        Dim ns As New XmlSerializerNamespaces()
        ns.Add("", "")


        Dim objStreamWriter As New StreamWriter("Invoice.xml") ' in the build folder
        Dim x As New XmlSerializer(faktura.GetType)
        x.Serialize(objStreamWriter, faktura, ns)
        objStreamWriter.Close()

        ' Dim objStreamReader As New StreamReader("Invoice.xml") ' in the build folder
        '  Dim DeserializeObj As New Invoice()
        ' DeserializeObj will contain your objects Deserialized from the Invoice.xml file
        ' DeserializeObj = x.Deserialize(objStreamReader)
        ' objStreamReader.Close()
    End Sub

    Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
        faktura.Osiguranik.Add(New Osiguranik() With {.Fil = txtFil.Text, .Isp = txtIsp.Text, .Prez = txtPrez.Text})
        txtFil.Text = ""
        txtIsp.Text = ""
        txtPrez.Text = ""
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        faktura.DodatneDijagnoze.Add(New DodatneDijagnoze() With {.DDijag = txtDDijag.Text})
        txtDDijag.Text = ""

    End Sub
End Class




<XmlRoot(ElementName:="Ustanova")>
Public Class Ustanova
    <XmlElement(ElementName:="Name")>
    Public Property Name() As String
        Get
            Return m_Name
        End Get
        Set
            m_Name = Value
        End Set
    End Property
    Private m_Name As String
    <XmlElement(ElementName:="LName")>
    Public Property LName() As String
        Get
            Return m_LName
        End Get
        Set
            m_LName = Value
        End Set
    End Property
    Private m_LName As String
    <XmlElement(ElementName:="Age")>
    Public Property Age() As String
        Get
            Return m_Age
        End Get
        Set
            m_Age = Value
        End Set
    End Property
    Private m_Age As String
End Class



<XmlRoot(ElementName:="Osiguranik")>
Public Class Osiguranik

    <XmlElement(ElementName:="Fil")>
    Public Property Fil() As String
        Get
            Return m_Fil
        End Get
        Set
            m_Fil = Value
        End Set
    End Property
    Private m_Fil As String
    <XmlElement(ElementName:="Isp")>
    Public Property Isp() As String
        Get
            Return m_Isp
        End Get
        Set
            m_Isp = Value
        End Set
    End Property
    Private m_Isp As String
    <XmlElement(ElementName:="Prez")>
    Public Property Prez() As String
        Get
            Return m_Prez
        End Get
        Set
            m_Prez = Value
        End Set
    End Property
    Private m_Prez As String

    <XmlElement(ElementName:="DodatneDijagnoze")>
    Public Property DodatneDijagnoze() As String
        Get
            Return m_DodatneDijagnoze
        End Get
        Set
            m_DodatneDijagnoze = Value
        End Set
    End Property
    Private m_DodatneDijagnoze As String

End Class

<XmlRoot(ElementName:="DodatneDijagnoze")>
Public Class DodatneDijagnoze

    <XmlElement(ElementName:="DDijag")>
    Public Property DDijag() As String
        Get
            Return m_DDijag
        End Get
        Set
            m_DDijag = Value
        End Set
    End Property
    Private m_DDijag As String

End Class




<XmlRoot(ElementName:="Faktura")>
Public Class Faktura

    Sub New()
        Me.Ustanova = New List(Of Ustanova)
        Me.Osiguranik = New List(Of Osiguranik)
    End Sub

    <XmlElement(ElementName:="Ustanova")>
    Public Property Ustanova() As List(Of Ustanova)
        Get
            Return m_Ustanova
        End Get
        Set
            m_Ustanova = Value
        End Set
    End Property
    Private m_Ustanova As List(Of Ustanova)



    <XmlElement(ElementName:="Osiguranik")>
    Public Property Osiguranik() As List(Of Osiguranik)
        Get
            Return m_Osiguranik
        End Get
        Set
            m_Osiguranik = Value
        End Set


    End Property
    Private m_Osiguranik As List(Of Osiguranik)


End Class

EDIT:

Here is Next Button:

faktura.Osiguranik.Add(New Osiguranik() With {.Fil = txtFil.Text, .Isp = txtIsp.Text, .Prez = txtPrez.Text, .DodatneDijagnoze = New DDijag() With {.DDijag = txtDDijag.Text}})

And here is my all code for making XML: (DodatneDijagnoze = Test, DDijag = Job)

<XmlRoot(ElementName:="Ustanova")>
Public Class Ustanova
    <XmlElement(ElementName:="Name")>
    Public Property Name() As String
        Get
            Return m_Name
        End Get
        Set
            m_Name = Value
        End Set
    End Property
    Private m_Name As String
    <XmlElement(ElementName:="LName")>
    Public Property LName() As String
        Get
            Return m_LName
        End Get
        Set
            m_LName = Value
        End Set
    End Property
    Private m_LName As String
    <XmlElement(ElementName:="Age")>
    Public Property Age() As String
        Get
            Return m_Age
        End Get
        Set
            m_Age = Value
        End Set
    End Property
    Private m_Age As String
End Class



<XmlRoot(ElementName:="Osiguranik")>
Public Class Osiguranik

    <XmlElement(ElementName:="Fil")>
    Public Property Fil() As String
        Get
            Return m_Fil
        End Get
        Set
            m_Fil = Value
        End Set
    End Property
    Private m_Fil As String
    <XmlElement(ElementName:="Isp")>
    Public Property Isp() As String
        Get
            Return m_Isp
        End Get
        Set
            m_Isp = Value
        End Set
    End Property
    Private m_Isp As String
    <XmlElement(ElementName:="Prez")>
    Public Property Prez() As String
        Get
            Return m_Prez
        End Get
        Set
            m_Prez = Value
        End Set
    End Property
    Private m_Prez As String

    <XmlElement(ElementName:="DodatneDijagnoze")>
    Public Property DodatneDijagnoze() As String
        Get
            Return m_DodatneDijagnoze
        End Get
        Set
            m_DodatneDijagnoze = Value
        End Set
    End Property
    Private m_DodatneDijagnoze As String

End Class

<XmlRoot(ElementName:="DDijag")>
Public Class DDijag

    <XmlElement(ElementName:="DDijag")>
    Public Property DDijag() As String
        Get
            Return m_DDijag
        End Get
        Set
            m_DDijag = Value
        End Set
    End Property
    Private m_DDijag As String

End Class




<XmlRoot(ElementName:="Faktura")>
Public Class Faktura

    Sub New()
        Me.Ustanova = New List(Of Ustanova)
        Me.Osiguranik = New List(Of Osiguranik)
    End Sub

    <XmlElement(ElementName:="Ustanova")>
    Public Property Ustanova() As List(Of Ustanova)
        Get
            Return m_Ustanova
        End Get
        Set
            m_Ustanova = Value
        End Set
    End Property
    Private m_Ustanova As List(Of Ustanova)



    <XmlElement(ElementName:="Osiguranik")>
    Public Property Osiguranik() As List(Of Osiguranik)
        Get
            Return m_Osiguranik
        End Get
        Set
            m_Osiguranik = Value
        End Set


    End Property
    Private m_Osiguranik As List(Of Osiguranik)

Got error Value of type 'DDijag' cannot be converted to 'String'.


EDIT:

I post app on English in comments.

Here is XML how looks:

<?xml version="1.0" encoding="utf-8"?>
<Invoice>
  <People>
    <Name>Test</Name>
    <LName>test</LName>
    <Age>42</Age>
  </People>
  <Family>
    <Sister>ttes</Sister>
    <Brother>ttsa</Brother>
    <F_Child>
      <SisterChild>dsads</SisterChild>
      <BrotherChild>sad</BrotherChild>
      <F_Child_Age>
        <SisterChildAge>fds</SisterChildAge>
        <BrotherChildAge>fdsfds</BrotherChildAge>
      </F_Child_Age>
    </F_Child>
  </Family>
</Invoice>

Now app can make unlimited entries of 'Family' like this:

<?xml version="1.0" encoding="utf-8"?>
<Invoice>
  <People>
    <Name>Test</Name>
    <LName>test</LName>
    <Age>42</Age>
  </People>
  <Family>
    <Sister>ttes</Sister>
    <Brother>ttsa</Brother>
    <F_Child>
      <SisterChild>dsads</SisterChild>
      <BrotherChild>sad</BrotherChild>
      <F_Child_Age>
        <SisterChildAge>fds</SisterChildAge>
        <BrotherChildAge>fdsfds</BrotherChildAge>
      </F_Child_Age>
    </F_Child>
  </Family>
  <Family>
    <Sister>dsa</Sister>
    <Brother>fds</Brother>
    <F_Child>
      <SisterChild>fds</SisterChild>
      <BrotherChild>fds</BrotherChild>
      <F_Child_Age>
        <SisterChildAge>fds</SisterChildAge>
        <BrotherChildAge>fds</BrotherChildAge>
      </F_Child_Age>
    </F_Child>
  </Family>
</Invoice>

I need to make unlimited entries in 'F_Child' in existing 'Family' *needs to look like this:

<?xml version="1.0" encoding="utf-8"?>
<Invoice>
  <People>
    <Name>Test</Name>
    <LName>test</LName>
    <Age>42</Age>
  </People>
  <Family>
    <Sister>ttes</Sister>
    <Brother>ttsa</Brother>
    <F_Child>
      <SisterChild>dsads</SisterChild>
      <BrotherChild>sad</BrotherChild>
      <F_Child_Age>
        <SisterChildAge>fds</SisterChildAge>
        <BrotherChildAge>fdsfds</BrotherChildAge>
      </F_Child_Age>
    </F_Child>
    <F_Child>
      <SisterChild>hggs</SisterChild>
      <BrotherChild>sgfffd</BrotherChild>
      <F_Child_Age>
        <SisterChildAge>fgds</SisterChildAge>
        <BrotherChildAge>fdgsfds</BrotherChildAge>
      </F_Child_Age>
    </F_Child>
  </Family>
  <Family>
    <Sister>dsa</Sister>
    <Brother>fds</Brother>
    <F_Child>
      <SisterChild>fds</SisterChild>
      <BrotherChild>fds</BrotherChild>
      <F_Child_Age>
        <SisterChildAge>fds</SisterChildAge>
        <BrotherChildAge>fds</BrotherChildAge>
      </F_Child_Age>
    </F_Child>
  </Family>
</Invoice>
Mile M.
  • 45
  • 1
  • 1
  • 10

1 Answers1

1

Personally I would use serialization for this like so.....

Imports System.IO
Imports System.Xml.Serialization

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Dim invoice As New Invoice

        ' replace this with the text from your textboxes on your form
        invoice.Person.Add(New Person() With {.Age = 29, .LName = "Doe", .Name = "John", .Test = New Job() With {.Job = Job.JobType.Yes}})
        invoice.Person.Add(New Person() With {.Age = 25, .LName = "Doe", .Name = "Jane", .Test = New Job() With {.Job = Job.JobType.No}})
        invoice.Person.Add(New Person() With {.Age = 55, .LName = "Doe", .Name = "Fred", .Test = New Job() With {.Job = Job.JobType.Yes}})
        invoice.Person.Add(New Person() With {.Age = 75, .LName = "Doe", .Name = "Harry", .Test = New Job() With {.Job = Job.JobType.No}})

        'Serialize object to a text file.
        Dim objStreamWriter As New StreamWriter("Invoice.xml") ' in the build folder
        Dim x As New XmlSerializer(invoice.GetType)

        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        ' simply add these two lines to remove the Namespaces by creating and setting XmlSerializerNamespaces to empty strings
        Dim ns = New XmlSerializerNamespaces()
        ns.Add("", "")
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

        ' then add ns the Serialize function
        x.Serialize(objStreamWriter, invoice, ns)
        objStreamWriter.Close()


        'Deserialize text file to a new object.
        Dim objStreamReader As New StreamReader("Invoice.xml") ' in the build folder
        Dim DeserializeObj As New Invoice()
        ' DeserializeObj will contain your objects Deserialized from the Invoice.xml file
        DeserializeObj = x.Deserialize(objStreamReader)
        objStreamReader.Close()

    End Sub


End Class

<XmlRoot(ElementName:="Person")>
Public Class Person
    <XmlElement(ElementName:="Name")>
    Public Property Name() As String
        Get
            Return m_Name
        End Get
        Set
            m_Name = Value
        End Set
    End Property
    Private m_Name As String
    <XmlElement(ElementName:="LName")>
    Public Property LName() As String
        Get
            Return m_LName
        End Get
        Set
            m_LName = Value
        End Set
    End Property
    Private m_LName As String
    <XmlElement(ElementName:="Age")>
    Public Property Age() As String
        Get
            Return m_Age
        End Get
        Set
            m_Age = Value
        End Set
    End Property
    Private m_Age As String

    <XmlElement(ElementName:="Test")>
    Public Property Test() As Job
        Get
            Return _TEST
        End Get
        Set(ByVal value As Job)
            _TEST = value
        End Set
    End Property
    Private _TEST As Job
End Class

<XmlRoot(ElementName:="Job")>
Public Class Job

    Public Enum JobType
        Yes
        No
    End Enum


    Private _Job As JobType
    Public Property Job() As JobType
        Get
            Return _Job
        End Get
        Set(ByVal value As JobType)
            _Job = value
        End Set
    End Property
End Class

<XmlRoot(ElementName:="Invoice")>
Public Class Invoice

    Sub New()
        Me.Person = New List(Of Person)
    End Sub
    <XmlElement(ElementName:="Person")>
    Public Property Person() As List(Of Person)
        Get
            Return m_Person
        End Get
        Set
            m_Person = Value
        End Set
    End Property
    Private m_Person As List(Of Person)
End Class

EDIT

You need to use a ComboBox for the selection of

<Job>Yes</Job> 

Put a ComboBox1 control on the Form and use the code below to display the JobType Enum values to select from

Me.ComboBox1.DataSource = System.Enum.GetValues(GetType(Job.JobType))

then on you 'Next' Button click event you would use like so....

invoice.Person.Add(New Person() With {.Age = TextBox1.Text, .LName = TextBox2.Text, .Name = TextBox3.Text, .Test = New Job() With {.Job = CType(ComboBox1.SelectedValue, Job.JobType)}})

EDIT for string

<XmlRoot(ElementName:="Job")>
Public Class Job
    Private _Job As String

    Public Property Job() As String
        Get
            Return _Job
        End Get
        Set(ByVal value As String)
            _Job = value
        End Set
    End Property
End Class

and to use.....

invoice.Person.Add(New Person() With {.Age = TextBox1.Text, .LName = TextBox2.Text, .Name = TextBox3.Text, .Test = New Job() With {.Job = "Yes"}})
Monty
  • 1,534
  • 2
  • 10
  • 12
  • I have 3 textboxes (txtName, txtLName, txtAge) and when I fill textboxes and click Next, after click textboxes cleared and I start filling new person. When I enter 20 persons I want to click export to XML, and got all 20 persons in XML file. Number of entries is changeable. – Mile M. May 23 '16 at 19:09
  • Well the code to create the XML is in my answer, all that is left for you to do is simply 'Add' a new Person (to invoice.Person) after each 'Next' click, then Serialize that to XML using XmlSerializer (on the export button click event)..... I've done the hard bit for you. If I simply write code that you can copy n paste you wont learn much.... – Monty May 23 '16 at 19:28
  • Thanks, I separate Form1_Load code to two buttons and all work fine. I only have one more question, I want to delete xsi and xsd namespaces I'm following this: https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializernamespaces(v=vs.110).aspx but without success. – Mile M. May 23 '16 at 20:19
  • OK cheers... that a look at this answer.. http://stackoverflow.com/questions/760262/xmlserializer-remove-unnecessary-xsi-and-xsd-namespaces.... i searcged Google for 'xmlserializer remove xsi xsd'.... – Monty May 23 '16 at 20:26
  • I see this http://stackoverflow.com/questions/760262/xmlserializer-remove-unnecessary-xsi-and-xsd-namespaces but I can't make to work. – Mile M. May 23 '16 at 20:45
  • I finally succeeded, following this http://stackoverflow.com/questions/258960/how-to-serialize-an-object-to-xml-without-getting-xmlns and make some little changes... Thanks for help with XML Serialization! – Mile M. May 23 '16 at 21:03
  • OK good.... I also found this answer which looks a pretty simple http://stackoverflow.com/questions/625927/omitting-all-xsi-and-xsd-namespaces-when-serializing-an-object-in-net, I have also modified my answer to show how you would use that solution in my example... – Monty May 23 '16 at 21:10
  • Please can you help me, I don't know how to make third Element.(Invoice>Person>Test) I updated my question with XML file please look. – Mile M. May 23 '16 at 23:18
  • Thanks for helping me, I got error. 'DodatneDijagnoze' is not a member of 'Faktura' I will upload all my code. – Mile M. May 24 '16 at 01:13
  • Please can you change to normal like olthers Strings. I don't need combobox. In my code Test is DodatneDijagnoze and Job is DDijag. – Mile M. May 24 '16 at 10:36
  • Yes, I do this but got error Value of type 'DDijag' cannot be converted to 'String'. I will update to post. – Mile M. May 24 '16 at 11:00
  • Seems like you have a local problem with your code that i cannot see, you will need to debug your code to understand what is going on.... – Monty May 24 '16 at 11:15
  • Please can you change ComboBox to String. May I make a mistake somewhere. I really need this code. – Mile M. May 24 '16 at 11:41
  • I have edited my answer, If you are changing the 'Names' of Classes etc you need to debug your code.... – Monty May 24 '16 at 12:06
  • Isn't working. I upload my test project. Please open project and see what is problem. Thank you very much for helping me!! – Mile M. May 24 '16 at 12:41
  • OK, find working code here http://www.mediafire.com/download/ej7dj69y0ddd67z/XML-PisacTest.rar.... and maybe upvote my answer for another 10 points Yes? – Monty May 24 '16 at 12:48
  • Thank you very much !! Now I know how to add more Elements in Elements! Yes I will Upvote your answer when I earn 15 ponts of reputation. Do not worry, I will write in my reminder! Thanks again for your help! – Mile M. May 24 '16 at 14:34
  • ahh, I have one more question. I need to add more 'Test' elements in one 'Person'. I want to add Person informations and Test>Job, And click on "next Test" and for the same person write two Test. After this click "Next Person". Thank you very much ! – Mile M. May 24 '16 at 16:24
  • Please can you help me? @Monty – Mile M. May 24 '16 at 18:16
  • You need to look at the code you have and extend your solution by understanding how it currently works, the problem is that you have changed the names of everything and I don't have the time to fix and translate the code any further, all the answers you need are in the code you currently have.... and besides that, if this is for education you will fail if you cannot understand the code so far.... – Monty May 24 '16 at 18:52
  • Please take a look of this. I post code and its much easier to understand. http://stackoverflow.com/questions/37422159/vb-net-xml-serialization-repeat-third-child-element – Mile M. May 24 '16 at 19:27
  • I took a look at that question Mile, it needs to be in English for me coz you seem to have changed the order of some things, your English is better than my Swedish, maybe I can take another look tomorrow if the XML is in English..... – Monty May 24 '16 at 23:30
  • Ok, no problem I will use your start code and add in English more Elements and post here code. Need 10-15min to make new code... – Mile M. May 24 '16 at 23:33
  • Here is new app on English. I will add/edit my post(question) how need XML looks. http://www.mediafire.com/download/hpv8u0kb96ptkuw/XML-Writer.zip @Monty – Mile M. May 25 '16 at 00:30
  • OK so i have answered the new question http://stackoverflow.com/questions/37422159/vb-net-xml-serialization-repeat-third-child-element/37431099#37431099 with example to add your XML Nodes.... i think something was wrong with your Classes in your code, this was making it very difficult to fix plus also being in a language I am not familiar with.... – Monty May 25 '16 at 08:01