Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save a DataSet ds.WriteXml(...) without <NewDataSet> Tag?

Tags:

c#

xml

I can read and write a XML File into a Dataset with no problems, but if I save the DataSet with ds.WriteXml("Testdata.xml") a additional Tag <NewDataSet>.......</NewDataSet> is generrated.

Is it possible to supress this Tag genaration?

like image 885
12 revs, 2 users 99% Avatar asked Mar 26 '11 12:03

12 revs, 2 users 99%


2 Answers

A dataset can contain multiple tables and a valid XML file must contain a single root node that's why it is wrapped in this node. You could specify the name of the root node when creating the DataSet:

var ds = new DataSet("root");

but if you want to remove it you could first load the DataSet into a XDocument or XmlDocument and then extract the node you need and save it into a file.

like image 159
Darin Dimitrov Avatar answered Sep 16 '22 15:09

Darin Dimitrov


I was looking to do the same thing in order to stream serialized DataRows without the overhead of tables and such. My solution was to use a temp DataTable as a sort of buffer which I fill with DataRows in chunks and then generate XML that I append to a stream. In order to reuse DataTable.WriteXml I had to solve the same problem and I wanted it to be efficient.

What I opted for is to create my own custom XmlWriter which is a lot simpler than it sounds. It works by skipping over elements that meet the condidtion of a predicate. In this case the predicate is whether the element name is the same as the expected DataSet name.

var writer = new RootlessDataSetXmlWriter(
    File.OpenWrite(@"C:\temp\ds.xml")
    "YourDataSetName");
dataSet.WriteXml(writer, XmlWriteMode.IgnoreSchema);
writer.Flush();
writer.Close();

Below is the implementation for RootlessDataSetXmlWriter and the ELementSkippingXmlWritter base class.

public class RootlessDataSetXmlWriter : ElementSkippingXmlWriter
{
    private string _dataSetName;

    public RootlessDataSetXmlWriter(Stream stream, string dataSetName)
        : base(stream, (e) => string.Equals(e, dataSetName, StringComparison.OrdinalIgnoreCase))
    {
        _dataSetName = dataSetName;
        this.Formatting = System.Xml.Formatting.Indented;
    }
}

public class ElementSkippingXmlWriter : XmlTextWriter
{
    private Predicate<string> _elementFilter;
    private int _currentElementDepth;
    private Stack<int> _sightedElementDepths;

    public ElementSkippingXmlWriter(Stream stream, Predicate<string> elementFilter)
        : base(stream, Encoding.UTF8)
    {
        _elementFilter = elementFilter;
        _sightedElementDepths = new Stack<int>();
    }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        if (_elementFilter(localName))
        {
            // Skip the root elements
            _sightedElementDepths.Push(_currentElementDepth);
        }
        else
        {
            base.WriteStartElement(prefix, localName, ns);
        }

        _currentElementDepth++;
    }

    public override void WriteEndElement()
    {
        _currentElementDepth--;

        if (_sightedElementDepths.Count > 0 && _sightedElementDepths.Peek() == _currentElementDepth)
        {
            _sightedElementDepths.Pop();
            return;
        }

        base.WriteEndElement();
    }
}
like image 45
jpierson Avatar answered Sep 17 '22 15:09

jpierson