DataColumn.Min/MaxLength

  • Thread starter Thread starter gerry
  • Start date Start date
G

gerry

Given the schema at the bottom of this post,
I am loading an xml document as follows,

DataSet ds = new DataSet();
ds.ReadXmlSchema( schemaFile );
ds.ReadXml( xmlFile );

This loads fine except that the ds.Tables["doc"].Columns["fld1"].MinLength &
MaxLength are -1 where I would have expected thne to be 1 & 10.
Is there some way to get the MinLength/MaxLength values to reflect the
restrictions setup in the schema ?
Or should the schema be setup somehow differently to achieve this ?

Gerry


<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:simpleType name="s10">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>

<xs:element name="doc">
<xs:complexType>
<xs:sequence>
<xs:element name="fld1" type="s10" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>

</xs:schema>
 
Hi Gerry,

We can design a DataSet in Visual Studio designer and then call
DataSet.WriteXMLSchema to ouput the right schema file. I do this in my side
and find that the DataSet column seems not support MinLength. So I get the
following schema,

<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>

And if I call ReadXmlSchema to import the schema into another DataSet, the
MaxLength property is set properly in my test. So the only issue here I
think is the MinLength is not supportted.

Hope this information helps!

Regards,
Ji Zhou
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).
 
Thanks Colbert

I setup a minimal console app to isolate this problem and it turns out that
if I read the dataset schema from file everything works
but if I read if from a stream it seems to just be ignored - not only the
maxLength property but the entire schema !

In the example below, reading the schema from file works as expected, the
dataset contains the table with the proper columns and column settings.
However after reading the schema from a stream the dataset is still empty -
so the dataset layout is determined solely by the contents of the xml which
is why the column settings from the schema are not having any effect.
All 3 versions of the schema give the same result ( the 1st one is mine ,
the second one is from an vs dataset designer WriteXmlSchema , the third is
the designer schema with a restriction defined. )

Any idea how we can get this to work when reading the schema from a stream -
is there a XmlReaderSettings property that I am not seeing ?

Gerry



using System;
using System.Data;
using System.IO;
using System.Reflection;
using System.Xml.Schema;
using System.Xml;

namespace Dbg
{
class Program
{
static void Main( string[] args )
{
string xsdPath = "c:\\tmp\\test.xsd";
string xmlPath = "c:\\tmp\\test.xml;

//-------------------------------------------------
// save dataset designer schema to file
//-------------------------------------------------
test ds1 = new test();
// ds1.WriteXmlSchema( xsdPath );
DumpDataSet( ds1 , "ds1" );

//-------------------------------------------------
// READ SCHEMA FROM FILE
// this dumps everything as expected
//-------------------------------------------------
DataSet ds2 = new DataSet();
ds2.ReadXmlSchema( xsdPath );
DumpDataSet( ds2 , "ds2" );

//-------------------------------------------------
// READ SCHEMA FROM STREAM
// without loading xml doc this dumps nothing
// if xml doc loaded, dumps expected tables/columns based on xml
parse - ie. maxLength = -1
//-------------------------------------------------
using ( XmlReader xsdReader = new XmlTextReader( "file:\\" +
xsdPath ) )
{
XmlSchema xsdSchema = XmlSchema.Read( xsdReader , null );
using ( DataSet ds3 = new DataSet() )
{
ds3 .ReadXmlSchema( xsdReader );
DumpDataSet( ds3 , "ds3" );
}
}
}

static void DumpDataSet( DataSet ds , string name )
{
Console.WriteLine( "\nDump {0}" , name );
foreach ( DataTable table in ds.Tables )
{
Console.WriteLine( "Table : {0}" , table.TableName );
foreach ( DataColumn column in table.Columns )
Console.WriteLine( " : {0} {1}" , column.ColumnName ,
column.MaxLength );
}
}

static void XmlValidationEventHandler( object sender ,
ValidationEventArgs e )
{
throw new Exception( string.Format( "Xml validation error @ line {0}
position {1} : {2}" ,
e.Exception.LineNumber , e.Exception.LinePosition ,
e.Message ) ,
e.Exception );
}
}
}


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:simpleType name="s10">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="table" >
<xs:complexType>
<xs:sequence>
<xs:element name="fld1" minOccurs="0" type="s10" />
<xs:element name="fld2" minOccurs="0" type="s10" />
<xs:element name="fld3" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

<?xml version="1.0" standalone="yes"?>
<xs:schema id="test" targetNamespace="http://tempuri.org/test.xsd"
xmlns:mstns="http://tempuri.org/test.xsd" xmlns=http://tempuri.org/test.xsd
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:msprop="urn:schemas-microsoft-com:xml-msprop"
attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:element name="test" msdata:IsDataSet="true"
msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="test" msprop:Generator_UserTableName="response"
msprop:Generator_TablePropName="_test">
<xs:complexType>
<xs:sequence>
<xs:element name="fld1" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="fld2" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="fld3" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

<?xml version="1.0" standalone="yes"?>
<xs:schema id="test" targetNamespace="http://tempuri.org/test.xsd"
xmlns:mstns="http://tempuri.org/test.xsd" xmlns=http://tempuri.org/test.xsd
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:msprop="urn:schemas-microsoft-com:xml-msprop"
attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="test" msdata:IsDataSet="true"
msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="test" msprop:Generator_UserTableName="response"
msprop:Generator_TablePropName="_test">
<xs:complexType>
<xs:sequence>
<xs:element name="fld1" minOccurs="0" type="s10" />
<xs:element name="fld2" minOccurs="0" type="s10" />
<xs:element name="fld3" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

<?xml version='1.0' standalone='yes'?>
<table>
<fld1>fld1</fld1>
<fld2>fld2</fld2>
<fld3>fld3</fld3>
</table>
 
Hi Germ,

I am still doing some future investigations on the information you provide.
If there is any found from my side, I will update to you as soon as
possible. Thanks for your patience, sir!

Have a nice day!

Regards,
Ji Zhou
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).
 
Hi Gerry,

According to the ReadXmlSchema function's documentation example, we need to
create the xmlReader by a FileStream and then read the schema from the
xmlReader.

The following codes work now for me,
static void Main(string[] args)
{
string xsdPath = "d:\\test\\test.xsd";
string xmlPath = "c:\\tmp\\test.xml";

//-------------------------------------------------
// save dataset designer schema to file
//-------------------------------------------------
test ds1 = new test();
// ds1.WriteXmlSchema( xsdPath );
DumpDataSet(ds1, "ds1");

//-------------------------------------------------
// READ SCHEMA FROM FILE
// this dumps everything as expected
//-------------------------------------------------
DataSet ds2 = new DataSet();
ds2.ReadXmlSchema(xsdPath);
DumpDataSet(ds2, "ds2");

//-------------------------------------------------
// READ SCHEMA FROM STREAM
// without loading xml doc this dumps nothing
// if xml doc loaded, dumps expected tables/columns based on
xml parse - ie. maxLength = -1
//-------------------------------------------------


System.IO.FileStream stream = new System.IO.FileStream
(xsdPath, System.IO.FileMode.Open);
System.Xml.XmlTextReader xmlReader =
new System.Xml.XmlTextReader(stream);
using (DataSet ds3 = new DataSet())
{
ds3.ReadXmlSchema(xmlReader);
DumpDataSet(ds3, "ds3");
}
}

Please try it and let me know if it works for you. Have a nice day!

Best regards,
Colbert Zhou
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).
 
ok - while considering your response and trying to figure out why the type
of stream should make any difference ( it doesn't ) I figured out what the
problem is.

I was trying to load the dataset using a validating reader and doing so was
I using the same stream for 2 different purposes - for schema validation and
for setting the dataset schema
Of course the 1st thing to use the reader 'emptied' it and the 2nd had
nothing to read.

In my test code that I posted , I had removed the validating reader bits but
I did leave in one the one line that caused the problem :

using ( XmlReader xsdReader = new XmlTextReader( "file:\\" +
xsdPath ) )
{

//--- removing this line solves the DataSet.ReadXmlSchema problem
// XmlSchema xsdSchema = XmlSchema.Read( xsdReader , null );

using ( DataSet ds3 = new DataSet() )
{
ds3 .ReadXmlSchema( xsdReader );
DumpDataSet( ds3 , "ds3" );
}
}



Having determined what the problem was , I thought that I could just forget
about loading the dataset schema and that it would be loaded properly from
the reader.
This doesn't seem to be the case at least as far as the maxLength property
is concerned.
I ended up rewinding the reader to get both a validating reader and a
properly configured dataset.

Here is the final working code :

using ( Stream xsdStream =
Assembly.GetExecutingAssembly().GetManifestResourceStream( xsdResID ) )
{
using ( XmlReader xsdReader = new XmlTextReader( xsdStream ) )
{
XmlSchema xsdSchema = XmlSchema.Read( xsdReader , null );
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.ValidationType = ValidationType.Schema;
readerSettings.Schemas.Add( xsdSchema );
readerSettings.ValidationEventHandler += new ValidationEventHandler(
XmlValidationEventHandler );
using ( XmlReader xmlReader = XmlTextReader.Create( new
StringReader( xml ) , readerSettings ) )
{
using ( DataSet ds4 = new DataSet() )
{
xsdStream.Seek( 0 , SeekOrigin.Begin );
ds4.ReadXmlSchema( xsdStream );
ds4.ReadXml( xmlReader );
DumpDataSet( ds4 , "ds4 - resource reader" );
}
}
}
}
 
Back
Top