2011-09-02 56 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