Как отобразить DataTable XML из WriteXml в удобном для чтения формате? - PullRequest
2 голосов
/ 02 сентября 2011

У меня есть несколько DataTables, которые я хочу экспортировать в файл, а затем посмотреть.Я могу использовать DataTable.WriteXml () для вывода содержимого DataTables в XML, но каков простой способ отобразить эти данные в виде таблицы?

Один из предлагаемых способов - преобразовать XML с использованием XSLT или аналогичного в нечто читаемое.Я понятия не имею, легко это или нет, но это было бы хорошим решением, если его легко использовать.

Ниже приведен пример XML, который я получаю от WriteXml () для одной таблицы данных.Это для таблицы с именем «RecentMatter» с 10 столбцами и 3 строками данных.Я хотел бы, чтобы это отображалось как таблица данных.Меня меньше беспокоит форматирование значений данных, например, преобразование значений DateTime в более читаемые значения.Я использовал параметр XmlWriteMode.WriteSchema при создании этого.Если вы удалите его, то вся информация схемы (до первого тега) будет удалена.

Разные таблицы, очевидно, будут иметь разное количество столбцов, поэтому любое решение должно будет иметь дело с этим, в идеале без необходимости изменятьрешение для таблиц с разными столбцами.

<NewDataSet>
<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="RecentMatter" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="RecentMatter">
<xs:complexType>
<xs:sequence>
<xs:element name="UserLogin">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="2147483647"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="MatterNumber">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="2147483647"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="ClientName">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="2147483647"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="MatterName">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="2147483647"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="ClientCode" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="2147483647"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="OfficeCode" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="2147483647"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="OfficeName" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="2147483647"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Billable" type="xs:boolean"/>
<xs:element name="ReferenceId" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="2147483647"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="LastUsed" type="xs:dateTime"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//RecentMatter"/>
<xs:field xpath="UserLogin"/>
<xs:field xpath="MatterNumber"/>
</xs:unique>
</xs:element>
</xs:schema>

<RecentMatter>
  <UserLogin>PSLTP6\RJK</UserLogin>
  <MatterNumber>99999-2302</MatterNumber>
  <ClientName>Test Matters</ClientName>
  <MatterName>DP Test Matter</MatterName>
  <ClientCode>99999</ClientCode>
  <OfficeCode/>
  <OfficeName/>
  <Billable>true</Billable>
  <ReferenceId/>
  <LastUsed>2011-08-23T23:40:24.13+01:00</LastUsed>
</RecentMatter>
<RecentMatter>
  <UserLogin>PSLTP6\RJK</UserLogin>
  <MatterNumber>999991.0002</MatterNumber>
  <ClientName>Lathe 1</ClientName>
  <MatterName>LW Test 2</MatterName>
  <ClientCode/>
  <OfficeCode/>
  <OfficeName/>
  <Billable>true</Billable>
  <ReferenceId/>
  <LastUsed>2011-07-12T16:57:27.173+01:00</LastUsed>
</RecentMatter>
<RecentMatter>
  <UserLogin>PSLTP6\RJK</UserLogin>
  <MatterNumber>999991-0001</MatterNumber>
  <ClientName>Lathe 1</ClientName>
  <MatterName>LW Test 1</MatterName>
  <ClientCode/>
  <OfficeCode/>
  <OfficeName/>
  <Billable>false</Billable>
  <ReferenceId/>
  <LastUsed>2011-07-12T01:59:06.887+01:00</LastUsed>
</RecentMatter>
</NewDataSet>

Ответы [ 2 ]

5 голосов
/ 02 сентября 2011

Дайте этому шанс. Вероятно, самый простой способ сериализации DataTable в XML:

DataTable table = new DataTable();    
System.IO.StringWriter writer = new System.IO.StringWriter();

//notice that we're ignoring the schema so we get clean XML back
//you can change the write mode as needed to get your result
table.WriteXml(writer, XmlWriteMode.IgnoreSchema, false);

string dataTableXml = writer.ToString();

Что касается отображения его в читаемом формате, я бы предложил передать XML в преобразователь XSL, который затем можно использовать для анализа XML и манипулирования выводом по мере необходимости.


Применение преобразования XSLT к набору данных

http://msdn.microsoft.com/en-us/library/8fd7xytc%28v=vs.71%29.aspx#Y289

Вот простой пример, который я создал, чтобы объяснить, как вы будете использовать XSL-преобразователь. Я не проверял это, но это должно быть довольно близко:

DataSet ds = new DataSet();
StringBuilder sbXslOutput = new StringBuilder();

using (XmlWriter xslWriter = XmlWriter.Create(sbXslOutput))
{
    XslCompiledTransform transformer = new XslCompiledTransform();
    transformer.Load("transformer.xsl");
    XsltArgumentList args = new XsltArgumentList();

    transformer.Transform(new XmlDataDocument(ds), args, xslWriter);
}

string dataSetHtml = sbXslOutput.ToString();

Форматирование XML как HTML с использованием XSLT

Вот пример использования XSLT для преобразования XML в таблицу HTML. Это должно быть довольно легко принять, чтобы вы могли использовать его с сериализованным набором данных.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
      <table border="1">
        <tr>
          <th>User Login</th>
          <th>Matter Number</th>
          ...
        </tr>
        <xsl:for-each select="NewDataSet/RecentMatter">
          <tr>
            <td>
              <xsl:value-of select="UserLogin"/>
            </td>
            <td>
              <xsl:value-of select="MatterNumber"/>
            </td>
            ...
          </tr>
        </xsl:for-each>
      </table>
  </xsl:template>
</xsl:stylesheet>
0 голосов
/ 02 сентября 2011

Этот метод, который я построил, может быть полезен для вас (при желании можно убрать украшение тире ...). Таблица должна отображаться так:

+----------+----------+----------+
| Column1  | Column2  | Column3  |
+----------+----------+----------+
| asdfasdf | asdfasdf | asdfasdf |
| asdfasdf | asdfasdf | asdfasdf |
| asdfasdf | asdfasdf | asdfasdf |
+----------+----------+----------+

Вот код:

public void WriteTable(DataTable table, Stream outputStream)
{
    // Create writer
    StreamWriter writer = new StreamWriter(outputStream);

    // Compute max lengths to build correct tabular columns
    Dictionary<string, int> maxLengths = new Dictionary<string, int>();

    foreach (DataColumn column in table.Columns)
    {
        maxLengths.Add(column.ColumnName, column.ColumnName.Length);

        foreach (DataRow row in table.Rows)
        {
            maxLengths[column.ColumnName] = Math.Max(
                maxLengths[column.ColumnName], 
                Convert.ToString(row[column.ColumnName]).Length);
        }
    }

    // Build horizontal rule to separate headers from data
    string horizontalRule = "+";

    foreach (DataColumn column in table.Columns)
    {
        horizontalRule += String.Format("-{0}-+", new string('-', maxLengths[column.ColumnName]));
    }

    writer.WriteLine(horizontalRule);

    // Write headers
    writer.Write("|");

    foreach (DataColumn column in table.Columns)
    {
        writer.Write(" {0," + (-(maxLengths[column.ColumnName])) + "} |", column.ColumnName);
    }

    writer.WriteLine();

    writer.WriteLine(horizontalRule);

    // Write data
    foreach (DataRow row in table.Rows)
    {
        writer.Write("|");

        foreach (DataColumn column in table.Columns)
        {
            writer.Write(" {0," + (-(maxLengths[column.ColumnName])) + "} |", row[column.ColumnName]);
        }

        writer.WriteLine();
    }

    writer.WriteLine(horizontalRule);

    // Close writer
    writer.Close();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...