Exception when reading a certain DataSet column loaded with the contents of an XML file

1

I have an XML file where I upload your data in a DataSet

DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("~/datos.xml"));

When trying to read the column 'NumCodigo' of the form:

ds.Tables["NumCodigo"].Rows[0]["NumCodigo"]

I have an exception with the following message:

  

The column 'NumCodigo' does not belong to the NumCodigo table. "

I have changed the name of this element in the XML file by NCodigo and then if I get the corresponding value that would be 123456.

ds.Tables["NCodigo"].Rows[0]["NumCodigo"]

But I need to access it by the name NumCodigo . If I access by index I also get the same error unless I change the name also by NCodigo .

The XML file is as follows:

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <Productos>
    <P11>1</P11>
    <P12>1</P12>
    <P14>1</P14>
    <P21>0</P21>
  </Productos>
  <Cantidades>
    <Tipo>A</Tipo>
    <Producto>P11</Producto>
    <NumCodigo>123456</NumCodigo>
  </Cantidades>
  <Cantidades>
    <Tipo>B</Tipo>
    <Producto>P12</Producto>
    <NumCodigo>123456</NumCodigo>
  </Cantidades>
  <Cantidades>
    <Tipo>C</Tipo>
    <Producto>P14</Producto>
    <NumCodigo>123456</NumCodigo>
  </Cantidades>
  <NumCodigo>
    <NumCodigo>123456</NumCodigo>
  </NumCodigo>
</NewDataSet>
    
asked by Popularfan 30.08.2018 в 17:47
source

1 answer

1

After performing some tests, it seems that DataSet.ReadXml is not able to correctly infer the data schema if there is a field whose name matches the name of the superior element. It is probably something inherent to the internal implementation of the method and the way of traversing the nodes to infer the schema of the data.

Having seen this, you have two options:

  • Rename the table so that it does not match the one in the column:

    ...
    <NumCodigos>
       <NumCodigo>123456</NumCodigo>
    </NumCodigos>
    
  • Include the schema of the data in your xml file. I'll put you as you would in your example:

    <?xml version="1.0" standalone="yes"?>
    <NewDataSet>
      <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:UseCurrentLocale="true">
          <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
              <xs:element name="Productos">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="P11" type="xs:int" minOccurs="0" />
                    <xs:element name="P12" type="xs:int" minOccurs="0" />
                    <xs:element name="P14" type="xs:int" minOccurs="0" />
                    <xs:element name="P21" type="xs:int" minOccurs="0" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element name="Cantidades">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Tipo" type="xs:string" minOccurs="0" />
                    <xs:element name="Producto" type="xs:string" minOccurs="0" />
                    <xs:element name="NumCodigo" type="xs:int" minOccurs="0" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element name="NumCodigo">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="NumCodigo" type="xs:int" minOccurs="0" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:choice>
          </xs:complexType>
        </xs:element>
      </xs:schema>
      <Productos>
        <P11>1</P11>
        <P12>1</P12>
        <P14>1</P14>
        <P21>0</P21>
      </Productos>
      <Cantidades>
        <Tipo>A</Tipo>
        <Producto>P11</Producto>
        <NumCodigo>123456</NumCodigo>
      </Cantidades>
      <Cantidades>
        <Tipo>B</Tipo>
        <Producto>P12</Producto>
        <NumCodigo>123456</NumCodigo>
      </Cantidades>
      <Cantidades>
        <Tipo>C</Tipo>
        <Producto>P14</Producto>
        <NumCodigo>123456</NumCodigo>
      </Cantidades>
      <NumCodigo>
        <NumCodigo>123456</NumCodigo>
      </NumCodigo>
    </NewDataSet>
    
  • If the xml file with the data is being generated by using DataSet.WriteXml , what you should do is add the XmlWriteMode.WriteSchema parameter to add the schema to the file:

    ds.WriteXml(Server.MapPath("~/datos.xml"),XmlWriteMode.WriteSchema);
    

    Edited

    There is a third option, which you can use if (as it seems to be your case) you do not have access to modify the xml file. This option is to generate the data schema in your DataSet before importing it. I'm going to use the example you've put:

    //Creamos las tablas y campos necesarios:
    
    DataTable dt1 = new DataTable("Productos");
    dt1.Columns.Add("P11", typeof(int));
    dt1.Columns.Add("P12", typeof(int));
    dt1.Columns.Add("P14", typeof(int));
    dt1.Columns.Add("P21", typeof(int));
    
    DataTable dt2 = new DataTable("Cantidades");
    dt2.Columns.Add("Tipo");
    dt2.Columns.Add("Producto");
    dt2.Columns.Add("NumCodigo", typeof(int));
    
    DataTable dt3 = new DataTable("NumCodigo");
    dt3.Columns.Add("NumCodigo");
    
    //Añadimos las tablas a un nuevo DataSet
    DataSet ds = new DataSet();
    ds.Tables.Add(dt1);
    ds.Tables.Add(dt2);
    ds.Tables.Add(dt3);
    
    //Ahora en ds ya tenemos el esquema de datos correcto. Ya podemos importar los datos
    
    ds.ReadXml(Server.MapPath("~/datos.xml"));
    var col = ds.Tables["NumCodigo"].Rows[0]["NumCodigo"];
    

    Using this method, you must bear in mind that the tables and fields that you generate must match the xml data schema, and if this varies, you must modify it in your code as well.

    Issue 2

    I think the optimal way to solve the problem in your case is to have the schema in an xsd file, and read it before importing the data. Summing up:

    • You create a datos.xsd file with the schema:

      <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:UseCurrentLocale="true">
        <xs:complexType>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="Productos">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="P11" type="xs:int" minOccurs="0" />
                  <xs:element name="P12" type="xs:int" minOccurs="0" />
                  <xs:element name="P14" type="xs:int" minOccurs="0" />
                  <xs:element name="P21" type="xs:int" minOccurs="0" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>
            <xs:element name="Cantidades">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="Tipo" type="xs:string" minOccurs="0" />
                  <xs:element name="Producto" type="xs:string" minOccurs="0"/>
                  <xs:element name="NumCodigo" type="xs:int" minOccurs="0" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>
            <xs:element name="NumCodigo">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="NumCodigo" type="xs:int" minOccurs="0" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:choice>
        </xs:complexType>
      </xs:element>
      </xs:schema>
      
    • Now, we use the ReadXmlSchema method to first read the schema and then import the data:

      DataSet ds = new DataSet();
      //leemos el esquema
      ds.ReadXmlSchema(Server.MapPath("~/datos.xsd"));
      //importamos los datos
      ds.ReadXml(Server.MapPath("~/datos.xml"));
      //accedemos a la columna
      var col = ds1.Tables["NumCodigo"].Rows[0]["NumCodigo"];
      
    answered by 31.08.2018 / 08:47
    source