Null elements don't appear in XMLTextWriter results

  • Thread starter Thread starter AFN
  • Start date Start date
A

AFN

I am running the code below to generate XML from a data table. But some
fields in the data table are Null for every record. Suppose field5 has a
null database value. I would expect to see:

<field5></field5> or <field5 />

but instead it doesn't even show the field at all for those records where
field5 is Null! Instead it just shows:

<field4>Whatever</field4>
<field6>Whatever</field6>

This concerns me because if people take XML file output and import into a
database, they won't even know field5 exists unless some of the records have
a non null value. But sometimes field5 is null in all records. So how do
I get the writer to make an empty <field5 /> representation so database
imports won't get screwed up? On a side note, where would I flush the
buffer in my code below?





Here's my code:

Public Shared Function GetXML(ByVal objDataTable As DataTable, ByVal
objXmlTextWriter As XmlTextWriter) As String


If IsNothing(objDataTable) Then

Throw New Exception("DataTable cannot be nothing")
End If 'End of If Not Nothing(objDataTable) Then

Dim intCounter As Int32

objXmlTextWriter.WriteStartElement(objDataTable.TableName)

For intCounter = 0 To objDataTable.Rows.Count - 1

objXmlTextWriter.WriteStartElement("Row")
Dim objDataColumn As DataColumn
For Each objDataColumn In objDataTable.Columns


objXmlTextWriter.WriteElementString(objDataColumn.ColumnName.ToString(),
objDataTable.Rows(intCounter).Item(objDataColumn.ColumnName).ToString())
Next
objXmlTextWriter.WriteEndElement()
Next

objXmlTextWriter.WriteEndElement()

Return objXmlTextWriter.ToString



End Function
 
AFN said:
I am running the code below to generate XML from a data table. But some
fields in the data table are Null for every record. Suppose field5 has a
null database value. I would expect to see:

<field5></field5> or <field5 />

but instead it doesn't even show the field at all for those records where
field5 is Null! Instead it just shows:

<field4>Whatever</field4>
<field6>Whatever</field6>

This concerns me because if people take XML file output and import into a
database, they won't even know field5 exists unless some of the records have
a non null value. But sometimes field5 is null in all records. So how do
I get the writer to make an empty <field5 /> representation so database
imports won't get screwed up?
....

Here's my code:

Here's mine:

Public Shared Function GetXML(ByVal dtDataTable As DataTable, ByVal
xwXmlTextWriter As XmlTextWriter) As String
If dtDataTable Is Nothing Then
Throw New Exception("DataTable cannot be nothing") ' Should
really use ApplicationException
End If 'End of If objDataTable Is Nothing Then

Dim intCounter As Int32

xwXmlTextWriter.WriteStartElement(dtDataTable.TableName)

Dim row As DataRow
For Each row In dtDataTable.Rows
xwXmlTextWriter.WriteStartElement("Row")
Dim col As DataColumn
For Each col In dtDataTable.Columns
xwXmlTextWriter.WriteElementString(col.ColumnName,
row(col).ToString())
Next
xwXmlTextWriter.WriteEndElement()
Next

xwXmlTextWriter.WriteEndElement()

Return xwXmlTextWriter.ToString()
End Function

Some comments:

1) If you're going to prefix variables with a type abbreviation, I recommend
against using "obj". Everything is an object, so that doesn't tell you
anything.
2) I generally use "For Each" loops instead of using an index unless I need
to use the index within the loop. The index is just an artifact of the fact
that you're looping.
3) You don't have to use ToString on strings. col.ColumnName is already a
string.
 
John Saunders said:
how

Here's mine:

Public Shared Function GetXML(ByVal dtDataTable As DataTable, ByVal
xwXmlTextWriter As XmlTextWriter) As String
If dtDataTable Is Nothing Then
Throw New Exception("DataTable cannot be nothing") ' Should
really use ApplicationException
End If 'End of If objDataTable Is Nothing Then

Dim intCounter As Int32

xwXmlTextWriter.WriteStartElement(dtDataTable.TableName)

Dim row As DataRow
For Each row In dtDataTable.Rows
xwXmlTextWriter.WriteStartElement("Row")
Dim col As DataColumn
For Each col In dtDataTable.Columns
xwXmlTextWriter.WriteElementString(col.ColumnName,
row(col).ToString())
Next
xwXmlTextWriter.WriteEndElement()
Next

xwXmlTextWriter.WriteEndElement()

Return xwXmlTextWriter.ToString()
End Function

Some comments:

1) If you're going to prefix variables with a type abbreviation, I recommend
against using "obj". Everything is an object, so that doesn't tell you
anything.
2) I generally use "For Each" loops instead of using an index unless I need
to use the index within the loop. The index is just an artifact of the fact
that you're looping.
3) You don't have to use ToString on strings. col.ColumnName is already a
string.



I appreciate your code suggestions. Thanks. I did not write the function
and you are absolutely correct.

BUT, it still doesn't solve my #1 problem of a missing <field5 /> when
field5 is null. Do you know how can I fix this?
 
AFN said:
has into



I appreciate your code suggestions. Thanks. I did not write the function
and you are absolutely correct.

BUT, it still doesn't solve my #1 problem of a missing <field5 /> when
field5 is null. Do you know how can I fix this?



I just realized that the previous programmer was calling the .net
framework's DataSet.GetXML() method instead of this custom function I
posted. Duh!!! My function does correctly show <field5 />. But does
anyone know why the built-in framework GetXML method does NOT show empty
elements?

Also, can anyone still comment on how I would empty the buffer in my code?
I don't understand that but I read that you should do that. I don't know
where in the code and how.
 
AFN said:
already



I just realized that the previous programmer was calling the .net
framework's DataSet.GetXML() method instead of this custom function I
posted. Duh!!! My function does correctly show <field5 />. But does
anyone know why the built-in framework GetXML method does NOT show empty
elements?

Why should it show empty elements? NULL in SQL doesn't mean empty, it means
not present or "I don't know".
Also, can anyone still comment on how I would empty the buffer in my code?
I don't understand that but I read that you should do that. I don't know
where in the code and how.

I don't see that you should "empty the buffer". The XmlWriter.ToString() at
the end will return the string representation of all the XML elements you've
written to it.
 
John Saunders said:
Why should it show empty elements? NULL in SQL doesn't mean empty, it means
not present or "I don't know".


I don't see that you should "empty the buffer". The XmlWriter.ToString() at
the end will return the string representation of all the XML elements you've
written to it.



It should show empty elements, IMO, to maintain the structure of the XML, so
that importing programs know that the field exists with a NULL value.
Otherwise, if field5 had Nulls in every record, in my example above, there
would be no <field5> reference anywhere in the XML and no importing program
would know of that field name.

Thanks for your reply again.
 
AFN said:
unless



It should show empty elements, IMO, to maintain the structure of the XML, so
that importing programs know that the field exists with a NULL value.
Otherwise, if field5 had Nulls in every record, in my example above, there
would be no <field5> reference anywhere in the XML and no importing program
would know of that field name.

Thanks for your reply again.

In that case, there should be two parts to the XML. One should be the
schema, which would indicate all of the fields possible in the data. The
other would be the data itself, which would have no entries for NULL fields.
 
Back
Top