Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read XML into a DataTable when the XML is in a particular namespace

Tags:

xml

datatable

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>
like image 232
Chris Fewtrell Avatar asked Dec 29 '22 10:12

Chris Fewtrell


1 Answers

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).

like image 194
marc_s Avatar answered Apr 16 '23 14:04

marc_s