2011-09-02 216 views
2

我有一些DataTables,我想出口到一个文件,然后看看。我可以使用DataTable.WriteXml()将DataTables的内容输出为XML,但以表格形式显示此数据的简单方法是什么?如何以可读格式显示WriteXml中的DataTable XML?

一种建议的方法是将使用XSLT或类似的XML转换为可读的东西。我不知道这是否容易,但如果易于使用,这将是一个很好的解决方案。

下面是一个从WriteXml()为单个DataTable获取的XML示例。这是针对名为'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> 
+1

您是否尝试用excel打开那些生成的XML?我认为你应该把它看作表格,至少在最近的Excel版本中。 –

+0

也许你应该这样做XMLWriter.Formatting = Formatting.Indented;我不知道你是否可以将DataTable存储到XmlWriter,如果是的话,这应该构造你是XML。 – Burimi

+0

在Excel中打开效果不佳:如果您未在XML中包含Xml架构信息,那么它将显示一个表格,但不包含列标题。包括xml模式使得它完全错误。它也以大的值出现,并且不能正确处理DataSet,将它们全部放在一张宽页上。 – Rory

回答

0

我建立的这种方法可能对你有用(如果你喜欢...可以删除短划线装饰)。它应使表所示:

+----------+----------+----------+ 
| 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(); 
} 
4

给这个一杆。也许最简单的方式来序列化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转换到DataSet

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(); 

使用XSLT

下面是使用XSLT将XML转换为HTML表的一个例子格式化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

当然,这很简单,它是“将XML传递给XSL转换器,然后您可以使用它来解析XML并根据需要操作输出”这就是我正在寻找的魔法:) – Rory

+0

@Rory:Can你编辑你的问题,并包含序列化DataTable中的一些XML?而且,你在输出方面正在寻找什么? –

+0

当然,完成了。我很想看到一个XSLT示例,用于将其转换为可读。 – Rory