Есть ли ошибка в XmlTextReader при открытии пустых таблиц данных? - PullRequest
2 голосов
/ 27 марта 2009

У меня возникают некоторые проблемы с использованием XmlSerializer и XmlTextReader в c # при сохранении DataTables, которые не содержат никаких данных. Это известная проблема и есть ли обходной путь? Когда пустой массив данных сохраняется с помощью XMLSerializer, генерируется следующий XML:

      <Values>
        <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
          <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="Values" msdata:UseCurrentLocale="true">
            <xs:complexType>
              <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="Values">
                  <xs:complexType>
                  </xs:complexType>
                </xs:element>
              </xs:choice>
            </xs:complexType>
          </xs:element>
        </xs:schema>
        <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" />
      </Values>

Когда XML-файл, содержащий его, перезагружается, XMLTextReader молча завершается сбоем и не загружает контент за пределы точки, в которой пустой объект данных записывается в XML. Эта проблема, по-видимому, вызвана отсутствием элемента xs: sequence / xs: element внутри xs: complexType. Это ошибка, и если да, то какой обходной путь?

Следующая программа на c # демонстрирует проблему. Он выведет dt3 в ноль из-за проблемы, описанной выше:

public class Data
{
    private DataTable dt1;
    private DataTable dt2;
    private DataTable dt3;

    public DataTable Dt1
    {
        get { return dt1; }
        set { dt1 = value; }
    }

    public DataTable Dt2
    {
        get { return dt2; }
        set { dt2 = value; }
    }

    public DataTable Dt3
    {
        get { return dt3; }
        set { dt3 = value; }
    }

    public void TestDataTables()
    {
        if(dt1 == null)
            Console.WriteLine("dt1 is null");
        if (dt2 == null)
            Console.WriteLine("dt2 is null");
        if (dt3 == null)
            Console.WriteLine("dt3 is null");
    }
}
class Program
{
    static void Main(string[] args)
    {
        // Create test object
        Data data = new Data();
        data.Dt1 = new DataTable("Test1");
        data.Dt1.Columns.Add("Foo");
        data.Dt2 = new DataTable("Test2");
        // Adding the following line make serialization work as expected
        //data.Dt2.Columns.Add("Foo");
        data.Dt3 = new DataTable("Test3");
        data.Dt3.Columns.Add("Foo");
        data.TestDataTables();

        // Save to XML
        TextWriter filewriter = new StreamWriter("foo.xml");
        XmlTextWriter writer = new XmlTextWriter(filewriter);
        writer.Formatting = Formatting.Indented;
        XmlSerializer s1 = new XmlSerializer(typeof(Data));
        s1.Serialize(writer, data);
        writer.Close();
        filewriter.Close();

        // Reload from XML
        TextReader filereader = new StreamReader("foo.xml");
        XmlTextReader reader = new XmlTextReader(filereader);
        XmlSerializer s2 = new XmlSerializer(typeof(Data));
        Data newData = s2.Deserialize(reader) as Data;
        newData.TestDataTables();

    }
}

Ответы [ 3 ]

0 голосов
/ 27 марта 2009

(после редактирования)

Спасибо за пример кода. Да, я бы согласился, что это ошибка. Для обходных путей ... ну, вы могли бы добавить столбец по умолчанию? Чтобы избежать перекрестного загрязнения, вы можете использовать ShouldSerialize*:

public bool ShouldSerializeDt1() {
    return dt1 != null && dt1.Columns.Count > 0;
}
public bool ShouldSerializeDt2() {
    return dt2 != null && dt2.Columns.Count > 0;
}
public bool ShouldSerializeDt3() {
    return dt3 != null && dt3.Columns.Count > 0;
}

По крайней мере, тогда dt2 опускается вместо dt3.

0 голосов
/ 11 мая 2009

Я только что разместил этот запрос на форуме MSDN:

Как можно сериализовать пустой объект DataTable в сеанс? http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataset/thread/4704d53c-ca3a-4da1-8257-b2b05c2e9e32

Прежде чем я начну новую тему здесь, это та же проблема, о которой вы сообщаете здесь, пожалуйста? Я не уверен, потому что я не использую никакой явной Seialization, я просто помещаю DataSet (содержащий DataTable без строк) в Session, который сохраняется / восстанавливается вне процесса.

0 голосов
/ 27 марта 2009

Я склонен использовать метод write xml для набора данных, вы можете попробовать это как обходной путь.

http://msdn.microsoft.com/en-us/library/system.data.dataset.writexml.aspx

...