Remove diffgram and NewDataSet tag from XML in c#

2019-08-06 10:31发布

问题:

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>

回答1:

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.



标签: c# xml dataset