将空元素反序列化为可为null的DataTable列

时间:2019-04-05 20:49:53

标签: c#

我正在将xml导入具有可空列的DataTable中。当一个元素为空时,我希望它以行中的空值导入,但是我收到一个错误“输入字符串的格式不正确”。在下面的示例中,代码将创建一个包含两列的DataTable-id不可为空,moneyValue可以为可空。它将xsd打印到控制台窗口-我注意到属性'nillable ='true'不存在-可能是这样吗?

Xsd:

<?xml version="1.0" encoding="utf-16"?>
<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="simpleTable" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="simpleTable">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="id" type="xs:int" />
              <xs:element name="moneyValue" type="xs:double" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>
using System;
using System.Data;
using System.IO;

namespace ConsoleApp9
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable("simpleTable");
            DataColumn dc = new DataColumn("id", typeof(int)) { AllowDBNull = false };
            dt.Columns.Add(dc);
            dc = new DataColumn("moneyValue", typeof(double)) { AllowDBNull = true };
            dt.Columns.Add(dc);

            StringWriter sw = new StringWriter();
            dt.WriteXmlSchema(sw);
            sw.Flush();

            // emit the schema
            Console.WriteLine(sw.ToString());

            DataRow dr = dt.NewRow();
            dr["id"] = 1;
            dr["moneyValue"] = 100;
            dt.Rows.Add(dr);

            // Some xml with two sample rows- the first one will work, the second will not
            string xml = @"<?xml version='1.0' encoding='utf-8'?>
<DocumentElement>
    <simpleTable>
        <id>2</id>
        <moneyValue>200</moneyValue>
    </simpleTable>
    <simpleTable>
        <id>3</id>
        <moneyValue/>
    </simpleTable>
</DocumentElement>";
            StringReader reader = new StringReader(xml);
            dt.ReadXml(reader);

            Console.ReadKey();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

问题是

<moneyValue/>

不为null但为空 您必须删除该元素...我知道这是一个简单的解决方案

@"<?xml version='1.0' encoding='utf-8'?>
<DocumentElement>
<simpleTable>
    <id>2</id>
    <moneyValue>200</moneyValue>
</simpleTable>
<simpleTable>
    <id>3</id>
</simpleTable>
</DocumentElement>"

如果您无法控制XML,则必须处理空元素,例如

 <moneyValue/>

您必须将列的类型从双精度切换为字符串。 但是,如果要在该列中加倍,则可以采用这种棘手的方法:添加第三列,并以以下方式基于基于moneyValue的表达式填充它:

DataTable dt = new DataTable("simpleTable");
DataColumn dc = new DataColumn("id", typeof(int)) { AllowDBNull =     false };
dt.Columns.Add(dc);
dc = new DataColumn("moneyValue", typeof(string)) { AllowDBNull = true };
dt.Columns.Add(dc);
dc = new DataColumn("moneyValueDouble", typeof(double)) { AllowDBNull = true };
dc.Expression = "IIF(moneyValue = '', null, moneyValue)";
dt.Columns.Add(dc);

StringWriter sw = new StringWriter();
dt.WriteXmlSchema(sw);
sw.Flush();

// emit the schema
Console.WriteLine(sw.ToString());

DataRow dr = dt.NewRow();
dr["id"] = 1;
dr["moneyValue"] = 100;
dt.Rows.Add(dr);

// Some xml with two sample rows- the first one will work, the second will not
string xml = @"<?xml version='1.0' encoding='utf-8'?>
<DocumentElement>
<simpleTable>
    <id>3</id>
    <moneyValue/>
   </simpleTable>
</DocumentElement>";
TextReader reader = new StringReader(xml);
dt.ReadXml(reader);

// not necessary just to have your old datatable
dt.Columns["moneyValueDouble"].Expression = null;
dt.Columns.Remove("moneyValue");
dt.Columns["moneyValueDouble"].ColumnName = "moneyValue";


Console.ReadKey();