1

I want to create/save some data in an xml format, which is saved in a 2 fields data table object (the second field "target" holds no data).

The final solution should look like this:

<?xml version="1.0" encoding="utf-8"?>
<body>
  <trans-unit>
    <source>Some Text-1</source>
    <target />
  </trans-unit>
  <trans-unit>
    <source>Some Text-2</source>
    <target />
  </trans-unit>
  <trans-unit>
    <source>Some Text-3</source>
    <target />
  </trans-unit>
  ...
</body>

So far I managed to produce this:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<body>
  <trans-unit>
    <source xmlns="Some Text-1" />
    <target />
    <source xmlns="Some Text-2" />
    <target />
    <source xmlns="Some Text-3" />
    <target />
    ...
</body>

with this code(too many comments, I know...):

Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
    Dim xdoc As New XmlDocument
    'Dim xTransUnit As List(Of XmlElement) = New List(Of XmlElement)

    Dim xRoot As XmlElement = xdoc.CreateElement("body")
    Dim xTU As XmlElement = xdoc.CreateElement("trans-unit")
    'Dim xSource As XmlElement = xdoc.CreateElement("source")
    'Dim xTarget As XmlElement = xdoc.CreateElement("target")
    xdoc.AppendChild(xdoc.CreateXmlDeclaration("1.0", "utf-8", "no"))
    xdoc.AppendChild(xRoot)

    For Each row As DataRow In dtTranslation.Rows
        Dim xList As List(Of XmlElement) = New List(Of XmlElement)
        'xList.Add(xdoc.CreateElement("source", row("Source").ToString()))
        'xList.Add(xdoc.CreateElement("target", row("Target").ToString()))
        'xList.Add(xdoc.CreateElement("source", row("Source").ToString()))
        'xList.Add(xdoc.CreateElement("target", row("Target").ToString()))
        'Dim xSource As XmlElement = xdoc.CreateElement("source")
        'Dim xTarget As XmlElement = xdoc.CreateElement("target")
        'xSource.InnerText = row("Source").ToString()
        'xTarget.InnerText = row("Target").ToString()
        'xTU.AppendChild(xFields(0))
        'xTU.AppendChild(xFields(1))
        'xFields.Add(xRoot)
        Dim xSource As XmlElement = xdoc.CreateElement("source", row("Source").ToString())
        Dim xTarget As XmlElement = xdoc.CreateElement("target", row("Target").ToString())
        'xSource.InnerText = row("Source").ToString()
        'xTarget.InnerText = row("Target").ToString()
        xRoot.AppendChild(xTU)
        xTU.AppendChild(xSource)
        xTU.AppendChild(xTarget)

        'xTU.AppendChild(xFields(0))
        'xTU.AppendChild(xFields(1))
    Next

    'xTU.AppendChild(xSource)
    'xTU.AppendChild(xTarget)
    'xRoot.AppendChild(xTU)


    'xdoc.DocumentElement.SetAttribute("version", "1.2")
    'xdoc.AppendChild(xdoc.CreateElement("xliff"))
    'xdoc.CreateElement("body")

    xdoc.Save("E:\Temp\TestXML-3.xml")

End Sub

Any help would be very appreciated!

3

2 Answers 2

0

This should do what you need. It takes the row/node names from the DataTable and the child nodes from the column names in the DataTable:

  Private Sub WriteXml()
    Dim filename = "C:\Junk\Junk.xml"
    Dim dataTable = GetDataTable()
    Dim xdc = DataTableToXmlDocument(dataTable, "body")
    xdc.Save(filename)
  End Sub

  Private Function GetDataTable() As DataTable
    Dim dtb As New DataTable("trans-unit")
    dtb.Columns.Add("source")
    dtb.Columns.Add("target")
    dtb.Rows.Add("Some Text-1", Nothing)
    dtb.Rows.Add("Some Text-2", Nothing)
    dtb.Rows.Add("Some Text-3", Nothing)
    dtb.Rows.Add("Some Text-4", Nothing)
    Return dtb
  End Function

  Private Function DataTableToXmlDocument(dtb As DataTable, rootNode As String) As XmlDocument
    Dim xdc = New XmlDocument()
    xdc.AppendChild(xdc.CreateXmlDeclaration("1.0", "utf-8", "no"))
    xdc.AppendChild(xdc.CreateElement(rootNode))
    For Each drw As DataRow In dtb.Rows
      Dim currentNode = xdc.DocumentElement.AppendChild(xdc.CreateElement(dtb.TableName))
      For i = 0 To dtb.Columns.Count - 1
        Dim currentElement = currentNode.AppendChild(xdc.CreateElement(dtb.Columns(i).ColumnName))
        If drw(i) IsNot DBNull.Value Then
          currentElement.AppendChild(xdc.CreateTextNode(drw(i)))
        End If
      Next i
    Next drw
    Return xdc
  End Function
Sign up to request clarification or add additional context in comments.

Comments

0
  1. Adapt your Datatable and use a DataSet:

    Dim dt As New DataTable("trans-unit")
    dt.Columns.Add("source", GetType(String))
    dt.Columns.Add("target", GetType(String))
    
    dt.Rows.Add("Some Text-1", String.Empty)
    dt.Rows.Add("Some Text-2", String.Empty)
    dt.Rows.Add("Some Text-3", String.Empty)
    
    Dim ds As New DataSet("body")
    ds.Tables.Add(dt)
    
  2. Use the XmlWriter class as follows:

    Imports System.Text
    Imports System.Xml
    
    Dim settings As New XmlWriterSettings With {
        .Indent = True,
        .Encoding = New UTF8Encoding(False),
        .OmitXmlDeclaration = False
    }
    
    Using writer As XmlWriter = XmlWriter.Create("output.xml", settings)
    
        writer.WriteStartDocument()
        ds.WriteXml(writer, XmlWriteMode.IgnoreSchema)
    End Using
    

The generated output.xml content will look as follows:

<?xml version="1.0" encoding="utf-8"?>
<body>
  <trans-unit>
    <source>Some Text-1</source>
    <target></target>
  </trans-unit>
  <trans-unit>
    <source>Some Text-2</source>
    <target></target>
  </trans-unit>
  <trans-unit>
    <source>Some Text-3</source>
    <target></target>
  </trans-unit>
</body>

The only disappoint with the code above is that does not generate autoclosed elements (<target />).

If you really require it, simply do these little changes:

Using writer As XmlWriter = XmlWriter.Create("output.xml", settings)

    writer.WriteStartDocument()
    writer.WriteRaw(Environment.NewLine)
    writer.WriteRaw(ds.GetXml())
End Using

Then the generated output.xml content will look as follows:

<?xml version="1.0" encoding="utf-8"?>
<body>
  <trans-unit>
    <source>Some Text-1</source>
    <target />
  </trans-unit>
  <trans-unit>
    <source>Some Text-2</source>
    <target />
  </trans-unit>
  <trans-unit>
    <source>Some Text-3</source>
    <target />
  </trans-unit>
</body>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.