tags:

views:

56

answers:

1

I want to read some XML data into a DataTable - using the ReadXml method like so

        var dataTable = new DataTable();
        XmlReader xmlReader = XmlReader.Create(new StringReader(xmlString));
        dataTable.ReadXml(xmlReader);

See below for the XML string. The XML includes the schema definition and everything is fine and dandy when the data has no namespace (i.e. is in the global namespace) but I cannot work out how to specify the schema and XML such that the XML data elements are in another namespace.

The exception I am getting is "DataTable 'cd:Motorcycles' does not match to any DataTable in source."

I know I am making some really stupid schoolboy error but I have been pulling my hair out now for an hour or so - fiddling without success.

Can someone put me put me out of my misery?

XML that works

          <NewDataSet xmlns="">
            <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="Motorcycles" msdata:UseCurrentLocale="true">
                <xs:complexType>
                  <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="Motorcycles">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="Manufacturer" type="xs:string" minOccurs="0" />
                          <xs:element name="PercentageOfRiders" type="xs:int" minOccurs="0" />
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:choice>
                </xs:complexType>
              </xs:element>
            </xs:schema>
            <Motorcycles>
              <Manufacturer>Honda</Manufacturer>
              <PercentageOfRiders>23</PercentageOfRiders>
            </Motorcycles>
            <Motorcycles>
              <Manufacturer>Yamaha</Manufacturer>
              <PercentageOfRiders>15</PercentageOfRiders>
            </Motorcycles>
            <Motorcycles>
              <Manufacturer>Suzuki</Manufacturer>
              <PercentageOfRiders>16</PercentageOfRiders>
            </Motorcycles>
            <Motorcycles>
              <Manufacturer>BMW</Manufacturer>
              <PercentageOfRiders>6</PercentageOfRiders>
            </Motorcycles>
            <Motorcycles>
              <Manufacturer>Other</Manufacturer>
              <PercentageOfRiders>40</PercentageOfRiders>
            </Motorcycles>
          </NewDataSet>

XML with namespace (doesn't work)

          <cd:NewDataSet xmlns="urn:ChartData" xmlns:cd="urn:ChartData">
            <xs:schema id="NewDataSet" 
                       targetNamespace="urn:ChartData" 
                       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                       xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
                       elementFormDefault="qualified">
              <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="cd:Motorcycles" msdata:UseCurrentLocale="true">
                <xs:complexType>
                  <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="Motorcycles">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="Manufacturer" type="xs:string" minOccurs="0" />
                          <xs:element name="PercentageOfRiders" type="xs:int" minOccurs="0" />
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:choice>
                </xs:complexType>
              </xs:element>
            </xs:schema>
            <cd:Motorcycles>
              <cd:Manufacturer>Honda</cd:Manufacturer>
              <cd:PercentageOfRiders>23</cd:PercentageOfRiders>
            </cd:Motorcycles>
            <cd:Motorcycles>
              <cd:Manufacturer>Yamaha</cd:Manufacturer>
              <cd:PercentageOfRiders>15</cd:PercentageOfRiders>
            </cd:Motorcycles>
            <cd:Motorcycles>
              <cd:Manufacturer>Suzuki</cd:Manufacturer>
              <cd:PercentageOfRiders>16</cd:PercentageOfRiders>
            </cd:Motorcycles>
            <cd:Motorcycles>
              <cd:Manufacturer>BMW</cd:Manufacturer>
              <cd:PercentageOfRiders>6</cd:PercentageOfRiders>
            </cd:Motorcycles>
            <cd:Motorcycles>
              <cd:Manufacturer>Other</cd:Manufacturer>
              <cd:PercentageOfRiders>40</cd:PercentageOfRiders>
            </cd:Motorcycles>
          </cd:NewDataSet>
+1  A: 

You need to take two things into account when reading this XML:

  • the XML namespace urn:ChartData
  • the name of the main data table inside the data set - you find this here:

    <xs:element name="NewDataSet" msdata:IsDataSet="true" 
                msdata:MainDataTable="cd:Motorcycles"  <== this name here is important
                msdata:UseCurrentLocale="true">
    

With those two things in mind, you need to change the way you instantiate the DataTable and then the reading works just fine:

// define the data table's name to be the value of the msdata:MainDataTable 
// attribute on the NewDataSet element, and define the XML namespace to use
DataTable dataTable = new DataTable("Motorcycles", "urn:ChartData");

XmlReader xmlReader = XmlReader.Create(new StringReader(xmlString));
dataTable.ReadXml(xmlReader);

Now, your dataTable should contains some entries in its .Rows property - five in my case (with your second example XML).

marc_s
Thank you Marc. As it happens, I cannot change the code that instantiates the DataTable (long story) - but at least I can now stop with my trial-and-erroring approach to getting it to work by manipulate the XML +schema.
Chris F