Groups | Blog | Home
all groups > dotnet xml > february 2005 >

dotnet xml : adding row to exiting xml file problem.


Todd
2/11/2005 5:09:03 AM
I have the following code that inserts a new element and its attributes into
an xml file. The problem is the syntax of the inserted row. here is my code:

'Create an XmlDataDocument.
Dim doc As XmlDataDocument = New XmlDataDocument
'Load the schema.
doc.DataSet.ReadXmlSchema("c:\animal.xsd")
Dim dtAnimals As DataTable = doc.DataSet.Tables.Item("animal")
'Load the XML data.
Dim reader As XmlTextReader = New XmlTextReader("c:\animal.xml")
doc.Load(reader)
reader.Close()
Dim root As XmlNode = doc.DocumentElement

' Create new animal element
Dim animalElement As XmlElement = doc.CreateElement("animal")
root.AppendChild(animalElement)

' Set animal attributes (type, name, age)
Dim typeAttribute As XmlAttribute = doc.CreateAttribute("type")
typeAttribute.InnerText = "dog"
animalElement.SetAttributeNode(typeAttribute)

Dim nameAttribute As XmlAttribute = doc.CreateAttribute("name")
nameAttribute.InnerText = "snoopy"
animalElement.SetAttributeNode(nameAttribute)

Dim ageAttribute As XmlAttribute = doc.CreateAttribute("age")
ageAttribute.InnerText = "10"
animalElement.SetAttributeNode(ageAttribute)

'Save File
doc.Save("c:\animal.xml")

The above code gives mr the following xml file, notice the closing animal
tag in the second row:

<?xml version="1.0"?>
<root>
<animal type="cat" name="garfield" age="3" />
<animal type="dog" name="snoopy" age="10"></animal>
</root>

I need my xml file to look like this:

<?xml version="1.0"?>
<root>
<animal type="cat" name="garfield" age="3" />
<animal type="dog" name="snoopy" age="10" />
</root>

Any ideas how I can accomplish this? I would perfer to use the
xmlDataDocument object as I will also have comments in the xml file that will
need to stay, and will most likly be displaying the xml file in a datagrid.

Derek Harmon
2/17/2005 9:00:42 PM
[quoted text, click to view]
\__> <animal type="dog" name="snoopy" age="10" />

Of course, these are perfectly equivalent representations (but you probably
already know that and are just handcuffed by a crumby XML consumer).

Instead of letting the Save( ) function wrap the file stream associated with
'animal.xml' in it's own XmlTextWriter, you need to supply your own. This
is because Save( ) will call WriteFullEndElement( ). You can't change that
Save( ) is implemented this way, but you can get around it with a custom
XmlTextWriter that performs a little sleight-of-hand by wiring these calls
to WriteEndElement( ).

An example of an XmlTextWriter that will do this is the following class.
[Vaguely reminiscent of the one I posted yesterday but in VB.NET.] ;-)

- - - XmlTextWriterEE.vb
Imports System
Imports System.IO
Imports System.Xml

' Wrapper that forces more compact empty element end
' tags to be written whenever possible.
'
Public Class XmlTextWriterEE
Inherits XmlTextWriter

' Create a new instance of XmlTextWriterEE around a TextWriter
' My base class does all the work.
'
Public Sub New( ByVal sink As System.IO.TextWriter sink )
MyBase.New( sink)
End Sub

' Intercept calls from XML producers that insist on always emiting
' a full end element (whether or not I've written child nodes) and
' route them to WriteEndElement instead.
'
Public Sub Overrides WriteFullEndElement( )
MyBase.WriteEndElement( )
End Sub

End Class
- - -

This XmlTextWriterEE class works with XmlDocument's Save( ) method in
this way,

Dim writerInner As TextWriter = New StreamWriter( "c:\animal.xml", False )
Dim writer As New XmlTextWriterEE( writerInner)
doc.Save( writer)


Derek Harmon

AddThis Social Bookmark Button