保存数据集ds.WriteXml(...)没有<newdataset>标记?</newdataset>

时间:2011-03-26 12:57:49

标签: c# xml

我可以在没有问题的情况下读取和写入数据集中的XML文件,但如果我使用ds.WriteXml("Testdata.xml")保存数据集,则会生成额外的标记<NewDataSet>.......</NewDataSet>

是否有可能压制这种标签?

3 个答案:

答案 0 :(得分:4)

数据集可以包含多个表,并且有效的XML文件必须包含单个根节点,这就是它包含在此节点中的原因。您可以在创建DataSet时指定根节点的名称:

var ds = new DataSet("root");

但是如果要删除它,可以先将DataSet加载到XDocumentXmlDocument中,然后提取所需的节点并将其保存到文件中。

答案 1 :(得分:1)

我希望做同样的事情,以便在没有表等开销的情况下流式化序列化DataRows。我的解决方案是使用临时DataTable作为一种缓冲区,我用块填充DataRows,然后生成我附加到流的XML。为了重用DataTable.WriteXml,我必须解决同样的问题,我希望它有效。

我选择的是创建我自己的自定义XmlWriter,它比听起来简单得多。它的工作原理是跳过符合谓词条件的元素。在这种情况下,谓词是元素名称是否与预期的DataSet名称相同。

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

以下是RootlessDataSetXmlWriter和ELementSkippingXmlWritter基类的实现。

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

答案 2 :(得分:0)

对于那些有效的&#34;像我一样,这里是简单的XDocument和XmlDocument codez(https://dotnetfiddle.net/s2VP0k的实例)。虽然XmlDocument在我的简单测试中通常更快,但我更喜欢XDocument的简单性。

的XDocument:

return System.Xml.Linq.XElement
    .Parse(xmlString)
    .FirstNode
    .ToString(); // <c><a>123</a></c>

的XmlDocument:

var xmlDoc = new System.Xml.XmlDocument();
xmlDoc.LoadXml(xmlString);
return xmlDoc.DocumentElement.InnerXml; // <c><a>123</a></c>