locked
DataSet.WriteXml does not output the xsi:nil="true" attribute RRS feed

  • Question

  • Case - incoming xml file gets read in, processed in c# and then output back to xml

    Issue - DataSet.WriteXml is not outputting the xsi:nil="true" attribute.

    question: am I missing something about the WriteXml method? I dont see properties to set how nulls will be output, I thought it was dependant on how the datset is created - which should be ok since the incoming file has xsi:nil="true".....do I need to do somthing to the dataset before calling WriteXml?

    More Info:
    I have an xml file that I am reading in with DataSet.ReadXml which has fields with null values.  These are flagged as such in the xml with nillable=true.

    The incoming file also flags the null fields with the xsi:nil="true" attribute (see sample incoming file).

    BUT...when I use DataSet.WriteXml, the xsd does not flag the fields as nilable and the null fields are omitted from the data.

    Sample incoming file:

    <?xml version="1.0" encoding="ISO8859-1"?>
    <ProDataSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="" xmlns:prodata="urn:schemas-progress-com:xml-prodata:0001">
    <xsd:element name="ProDataSet" prodata:proDataSet="true">
    <xsd:complexType>
    <xsd:sequence>
    <xsd:element name="cpy_titem" minOccurs="0" maxOccurs="unbounded">
    <xsd:complexType>
    <xsd:sequence>
    <xsd:element name="company" type="xsd:string" nillable="true"/>
    <xsd:element name="item-number" type="xsd:string" nillable="true"/>
    <xsd:element name="gtin-code" type="xsd:string" nillable="true"/>

    .....
    <cpy_titem>
    <company>adi</company>
    <item-number>01-1000</item-number>
    <gtin-code xsi:nil="true"/>
    ......

    <ProDataSet>
    <xs:schema id="ProDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="ProDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:element name="cpy_titem" minOccurs="0" maxOccurs="79228162514264337593543950335">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="company" type="xs:string" minOccurs="0" />
    <xs:element name="item-number" type="xs:string" minOccurs="0" />
    <xs:element name="upc-code" type="xs:string" minOccurs="0" />
    <xs:element name="gtin-code" type="xs:string" minOccurs="0" />
    .....

    <cpy_titem>
    <company>adi</company>
    <item-number>01-1000</item-number>
    <upc-code>01-1000</upc-code>
    <item-status>New</item-status>
    <def-cost>80.0</def-cost>
    .....

    Sample outgoing file (after using DataSet.WriteXml):

    Thursday, October 22, 2009 8:14 PM

All replies

  • The documentation at http://msdn.microsoft.com/en-us/library/ms172138.aspx the following:

    the following rules apply for an instance of DataRow.["columnName"] null assignments:

    1. The default default value is DbNull.Value for all except the strongly typed null columns where it is the appropriate strongly typed null value.

    2. Null values are never written out during serialization to XML files (as in "xsi:nil").

    3. All non-null values, including defaults, are always written out while serializing to XML. This is unlike XSD/XML semantics where a null value (xsi:nil) is explicit and the default value is implicit (if not present in XML, a validating parser can get it from an associated XSD schema). The opposite is true for a DataTable : a null value is implicit and the default value is explicit.

    4. All missing column values for rows read from XML input are assigned NULL. Rows created using NewRow or similar methods are assigned the DataColumn's default value.

    5. The IsNull method returns true for both DbNull.Value and INullable.Null .

    So I am afraid xsi:nil in the schema language does not apply to how the DataSet/DataTable handles null values in columns.
    MVP XML My blog
    Friday, October 23, 2009 10:21 AM
  • Thanks for the info.  I reviewed the link on null values.

    I have a followup question.

    Is there anyway through the xmlwriter settings or any other way to have DataSet.WriteXml output the xsi:nil="true" attribute or at least the nillable='true' attribute in the output xsd?

    When I create the dataset via read xml and my xsd has nillable=true and the data has xsi:nil=true, I would expect that at least the schema portion of the xml output would have nillable=true in the column tags?...but it does not.

    The destination of this xml file is not a .Net app - and the destination program is expecting the nillable="true" in the xsd and xsi:nil=true for null fields in the data. 

    I guess I could write out the xml myself, but that would seem to defeat the entire purpose of DataSet.WriteXml....

    Thanks again,
    Bryan 
    • Proposed as answer by RTomes Monday, December 14, 2009 8:36 PM
    Monday, October 26, 2009 6:38 PM
  • MORE info....

    I have done some additional testing and it appears that it is actually the DataSet.ReadXml that is not recognizing the xsi:nil="true" attribute.

    After loading the xml, I cycle thru the records and the fields that were flagged as null in the xml are now "" (blank) in the datatset.

    Has anyone experienced this?

    All I really want to do is have my xml read into c#, do some processing on it, and write it out to xml again (and retain the null attributes in my output xml).  This cant be this hard!!...

    The issue being that the columns that are flagged as nillable=true, with data flagged as xsi:nil="true" seem to get ignored by DataSet.ReadXml and DataSet.WriteXml.

    I tried using an XmlDataDocument and interestingly enough, the nil attributes are written out when I reference the XmlDataDocument.OuterXml.

    BUT - this only works for rows that are in the original xml - if you add a row to the dataset, the null cols are omitted....

    Also, you cant add any tables once you link the dataset to the xmldatadocument, so this may not work for me anyways, but I almost got somewhere.

    System.Xml.XmlDataDocument xmldd = new System.Xml.XmlDataDocument();

     

     

    System.IO.TextReader tr = new System.IO.StringReader(myxml);
    System.Xml.
    XmlReader reader = new System.Xml.XmlTextReader(tr);
    xmldd.DataSet.ReadXmlSchema(reader);  // load in the schema
    xmldd.LoadXml(myxml);  // load in the data 
    this.dstemp = xmldd.DataSet;


    if I add records to the tables inside dstemp - the xmldatadocument is updated, which is great, but again only the original rows output the nulls....

    anyways,
    thanks again!

     

     

     

    Tuesday, October 27, 2009 6:31 PM