在c#中从XML中删除diffgram和NewDataSet标记

时间:2014-12-08 14:20:11

标签: c# xml dataset

我想从xml中删除diffgramNewDataSet标记。

<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>

我已经通过XmlSerializer从dataset生成了这个xml。我使用了以下代码。

           //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());
                }
            }

我想从<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">删除<NewDataSet>xml代码。并且还想从 MACNET 标记中删除diffgr:id="MACNET1" msdata:rowOrder="0" diffgr:hasChanges="inserted"。我该如何删除?

我想要以下类型的输出

<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 个答案:

答案 0 :(得分:2)

要做的第一件事是通过DataSet.GetXml()DataSet.WriteXml()DataTable.WriteXml()方法序列化DataSet,而不是尝试序列化DataSet XmlSerializer。这会跳过所有diffgram废话,并产生以下输出:

<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>

现在,根据您创建DataSet的方式,<NewDataSet>根节点可能不存在,您就完成了。但是如果<NewDataSet>节点存在,并且您想要生成没有它的XML字符串,则可以使用此处建议的RootlessDataSetXmlWriterSave a DataSet ds.WriteXml(…) without <NewDataSet> Tag?,并添加一个接受{TextWriter的构造函数。 1}}:

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.
} 

然后将其称为

        string xml;
        using (var textWriter = new StringWriter())
        using (var writer = new RootlessDataSetXmlWriter(textWriter, ds.DataSetName))
        {
            ds.WriteXml(writer);
            xml = textWriter.ToString();
        }

这给出了以下输出:

<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>

这是你需要的。但请注意,如果您的根MACNET表有多行,则生成的XML将无效,因为all XML documents must have one and only one root tag