Вложенный XML: как динамически отображать данные, присутствующие во вложенном XML на странице HTML

#c# #html #xml #asp.net-core #model-view-controller

#c# #HTML #xml #asp.net-core #модель-представление-контроллер

Вопрос:

Требование: Пользователи могут предоставить любой XML-файл (вместе с файлом XSD, который содержит схему XML-файла), содержащий данные. Мне нужно показать «предварительный просмотр данных» на asp.net основной веб-сайт, а также необходимо сохранить схему XML в иерархической структуре в базе данных (сохранить все поля, присутствующие в XML, в таблице DB).

Текущий подход: в asp.net на основном веб-сайте у меня есть контроллер и соответствующее действие для того же. В View.cshtml у меня есть два элемента управления ‘file’ для получения ‘XML-файла’ и ‘XSD-файла’ от пользователя.

Примером файла XSD является

 <?xml version="1.0"?>
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="PM">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" name="Employee_Level1">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="0" name="Id" type="xs:string" />
              <xs:element minOccurs="0" name="Company" type="xs:string" />
              <xs:element minOccurs="0" name="Gender" type="xs:string" />
              <xs:element minOccurs="0" name="Email" type="xs:string" />
              <xs:element minOccurs="0" name="Account">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element minOccurs="0" name="BankName" type="xs:string" />
                    <xs:element minOccurs="0" name="AccountNo" type="xs:string" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element minOccurs="0" name="Payment_Level1">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="0" name="Company" type="xs:string" />
              <xs:element minOccurs="0" name="PaymentNo" type="xs:string" />
              <xs:element minOccurs="0" name="Currency" type="xs:string" />
              <xs:element minOccurs="0" name="Amount" type="xs:string" />
              <xs:element minOccurs="0" name="Attribute">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element minOccurs="0" name="AttributeName" type="xs:string" />
                    <xs:element minOccurs="0" name="AttributeContent" type="xs:decimal" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element minOccurs="0" name="PaidPayment_Level1">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="0" name="Company" type="xs:string" />
              <xs:element minOccurs="0" name="PaymentNo" type="xs:string" />
              <xs:element minOccurs="0" name="Currency" type="xs:string" />
              <xs:element minOccurs="0" name="Amount" type="xs:string" />
              <xs:element minOccurs="0" name="Attribute">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element minOccurs="0" name="AttributeName" type="xs:string" />
                    <xs:element minOccurs="0" name="AttributeContent" type="xs:decimal" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
  

Соответствующий этому файлу XSD файл XML является

 <?xml version="1.0" encoding="UTF-8"?>
<RootTop xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Employee_Level1>
        <Id>GS1</Id>
        <Company>Apple</Company>
        <Gender>Male</Gender>
        <Email>Apple@Apple.com</Email>
        <Account>
            <BankName>Axis</BankName>
            <AccountNo>4235</AccountNo>
        </Account>
    </Employee_Level1>
    <Employee_Level1>
        <Id>GS2</Id>
        <Company>Amazone</Company>
        <Gender>Male</Gender>
        <Email>Amazone@Amazone.com</Email>
        <Account>
            <BankName>HDFC</BankName>
            <AccountNo>123</AccountNo>
        </Account>
    </Employee_Level1>
    
    <Payment_Level1>
        <Company>Apple</Company>
        <PaymentNo>1813424</PaymentNo>
        <Currency>RS</Currency>
        <Amount>60.15</Amount>
        <Attribute>
            <AttributeName>Discount</AttributeName>
            <AttributeContent>15</AttributeContent>
        </Attribute>
    </Payment_Level1>
    <Payment_Level1>
        <Company>Amazone</Company>
        <PaymentNo>7643</PaymentNo>
        <Currency>EUR</Currency>
        <Amount>17849.15</Amount>
        <Attribute>
            <AttributeName>Discount</AttributeName>
            <AttributeContent>12</AttributeContent>
        </Attribute>
    </Payment_Level1>
    
    <PaidPayment_Level1>
        <Company>Apple</Company>
        <PaymentNo>41</PaymentNo>
        <Currency>EUR</Currency>
        <Amount>17849.15</Amount>
        <Attribute>
            <AttributeName>Discount</AttributeName>
            <AttributeContent>13</AttributeContent>
        </Attribute>
    </PaidPayment_Level1>
    <PaidPayment_Level1>
        <Company>Amazone</Company>
        <PaymentNo>56</PaymentNo>
        <Currency>EUR</Currency>
        <Amount>68.15</Amount>
        <Attribute>
            <AttributeName>Discount</AttributeName>
            <AttributeContent>13</AttributeContent>
        </Attribute>
    </PaidPayment_Level1>
    
    <PaidPayment_Level1>
        <Company>EMM-NL</Company>
        <PaymentNo>1813424</PaymentNo>
        <Currency>EUR</Currency>
        <Amount>17849.15</Amount>
        <Attribute>
            <AttributeName>Discount</AttributeName>
            <AttributeContent>1515</AttributeContent>
        </Attribute>
    </PaidPayment_Level1>
</RootTop>
  

Я считываю данные из XML-файла на c #, используя следующий код, и загружаю данные / схему в DataSet.

  public static DataSet CreateDataTableFromXmlFile(byte[] xsdFileContent, byte[] xmlFileContent)
 {
     DataSet ds = new DataSet();
     ds.ReadXmlSchema(new MemoryStream(xsdFileContent));

     foreach (DataTable tab in ds.Tables)
     {
        tab.BeginLoadData();
     }
     ds.ReadXml(new MemoryStream(xmlFileContent));
     foreach (DataTable tab in ds.Tables)
     {
        tab.EndLoadData();
     }
            
      return ds;
}
  

Как только данные находятся в наборе данных, у нас есть все данные, представленные в виде таблиц.

Отображение данных в пользовательском интерфейсе с помощью кода

 <div>
       @foreach (DataTable table in Model.DtSourcePreview.Tables)
       {
           @CreateTableChild(table);
       }
</div>

@functions
{
   public string CreateTableChild(DataTable table)
   {
       <table class="table mb-0">
           <thead>
               <tr>
               @foreach (DataColumn col in table.Columns)
               {
                  <th scope="col">@col.ColumnName</th>
               }
               </tr>
            </thead>
            <tbody>
               @foreach (DataRow row in table.Rows)
               {
                   <tr>
                   @foreach (DataColumn col in table.Columns)
                   {
                        <td>@row[col.ColumnName]</td>
                   }
                   </tr>
                }
             </tbody>
        </table>
        return "";
    }
}
  

используя этот код cshtml, я могу показать все таблицы в пользовательском интерфейсе, но данные не отображаются в иерархическом порядке. например, таблица учетных записей содержит все учетные записи (всех сотрудников), но нам нужно показать учетные записи под каждым соответствующим сотрудником.
Как мы можем этого добиться?

Как получить, какая таблица находится на каком уровне в XML?

Подробная информация:

  1. DataTable в DataSet также содержит отношения, DataTable.Дочерние элементы
  2. Новый столбец автоматически добавляется в родительскую и дочернюю таблицы для связей. Как мы можем отличить автоматически добавляемый столбец от исходных столбцов?

Ответ №1:

Мы можем достичь этого с помощью следующего кода

  @foreach (DataTable table in Model.DtSourcePreview.Tables)
                          {
                              if (IsParent(Model.DtSourcePreview, table))
                              {
                                  @CreateTableChild(Model.DtSourcePreview, table);
                              }
                         }
  

Метод заключается в

  public bool IsParent(DataSet dataSet, DataTable dataTable)
            {
                bool isParent = true;

                if (dataSet.Relations.Count > 0)
                {
                    foreach (var abc in dataSet.Relations)
                    {
                        if (((DataRelation)abc).ChildTable.TableName == dataTable.TableName)
                        {
                            isParent = false;
                        }
                    }
                }
                else
                {
                    isParent = true;
                }

                return isParent;
            }