I want to remove the diffgram
and NewDataSet
tag from xml.
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet>
<MACNET diffgr:id="MACNET1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
<BATCH_ID>131070</BATCH_ID>
<BATCH_Date_Submitted>12/1/2014 7:36:06 AM</BATCH_Date_Submitted>
<BATCH_Date_Received>12/1/2014 7:36:06 AM</BATCH_Date_Received>
</MACNET>
</NewDataSet>
</diffgr:diffgram>
I have generated this xml from dataset
by XmlSerializer. I have used following code.
//Serialize dataset
using (var memoryStream = new MemoryStream())
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
using (TextWriter streamWriter = new StreamWriter(memoryStream))
{
var xmlSerializer = new XmlSerializer(typeof(DataSet));
xmlSerializer.Serialize(streamWriter, ds, ns);
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
}
I want to remove <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
and <NewDataSet>
tag from xml
. and also want to remove diffgr:id="MACNET1" msdata:rowOrder="0" diffgr:hasChanges="inserted"
from MACNET tag. How can I remove this?
I want following type of output
<MACNET>
<BATCH_ID>131070</BATCH_ID>
<BATCH_Date_Submitted>12/1/2014 7:36:06 AM</BATCH_Date_Submitted>
<BATCH_Date_Received>12/1/2014 7:36:06 AM</BATCH_Date_Received>
</MACNET>
The first thing to do is to serialize the DataSet
via the DataSet.GetXml()
, DataSet.WriteXml()
or DataTable.WriteXml()
methods, rather than trying to serialize the DataSet
with an XmlSerializer
. This skips all the diffgram
nonsense and produces the following output:
<NewDataSet>
<MACNET>
<BATCH_ID>131070</BATCH_ID>
<BATCH_Date_Submitted>12/1/2014 7:36:06 AM</BATCH_Date_Submitted>
<BATCH_Date_Received>12/1/2014 7:36:06 AM</BATCH_Date_Received>
</MACNET>
</NewDataSet>
Now, depending on how you created your DataSet
, the <NewDataSet>
root node might not be present, and you are done. But if the <NewDataSet>
node is present, and you want to generate an XML string without it, you can use the RootlessDataSetXmlWriter
suggested here: Save a DataSet ds.WriteXml(…) without <NewDataSet>
Tag?, with an added constructor that accepts a TextWriter
:
public class RootlessDataSetXmlWriter : ElementSkippingXmlWriter
{
private readonly string _dataSetName;
public RootlessDataSetXmlWriter(TextWriter stream, string dataSetName)
: base(stream, (e) => string.Equals(e, dataSetName, StringComparison.OrdinalIgnoreCase))
{
_dataSetName = dataSetName;
this.Formatting = System.Xml.Formatting.Indented;
}
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(TextWriter writer, Predicate<string> elementFilter)
: base(writer)
{
_elementFilter = elementFilter;
_sightedElementDepths = new Stack<int>();
}
public ElementSkippingXmlWriter(Stream stream, Predicate<string> elementFilter)
: base(stream, Encoding.UTF8)
{
_elementFilter = elementFilter;
_sightedElementDepths = new Stack<int>();
}
// Rest is as shown in the linked answer.
}
And then call it like
string xml;
using (var textWriter = new StringWriter())
using (var writer = new RootlessDataSetXmlWriter(textWriter, ds.DataSetName))
{
ds.WriteXml(writer);
xml = textWriter.ToString();
}
This gives the following output:
<MACNET>
<BATCH_ID>131070</BATCH_ID>
<BATCH_Date_Submitted>12/1/2014 7:36:06 AM</BATCH_Date_Submitted>
<BATCH_Date_Received>12/1/2014 7:36:06 AM</BATCH_Date_Received>
</MACNET>
which is what you require. Note, however, if your root MACNET
table has more than one row, the XML produced will be invalid, since all XML documents must have one and only one root tag.