2013-06-25 39 views
0

我已經得到了描述某些我想要編輯的數據(模板)的XML。我將XML加載到DataSet中(請參見下面的圖1),將DataSet表插入DataGridView(使用單獨的組合框在它們之間切換),進行更改並保存XML(簡單的DataSet.WriteXML指令)。我讀的XML看起來非常好,並且可以被人類閱讀(見下面的圖2),但是,寫入的XML並不在原始附近(見下面的圖3)。C#DataSet XML加載和保存

我的目標是讓XML文檔的編輯和保存時相同的形式保存。

我在做什麼錯?代碼/ XML塊在下面。

圖1 - 讀取XML數據集到:

using (XmlReader xrMeta = XmlReader.Create(new StreamReader(ofdOpenXML.FileName))) 
    { 
     while (!xrMeta.EOF) 
     { 
      xrMeta.ReadToFollowing("record"); 
      if (xrMeta.NodeType == XmlNodeType.Element) 
      { 
      xrMeta.ReadToFollowing("fields"); 

      xrSub = xrMeta.ReadSubtree(); 
      dt = new DataTable(); 

      ds = new DataSet(); 

      ds.ReadXml(xrSub); 
      dt = ds.Tables[0].Copy(); 

      dt.TableName = "recordTypeId " + iTableNumber.ToString().PadLeft(2, '0'); 
      MetaXML.Tables.Add(dt); 
      iTableNumber++; 
      } 

     } 

     dgvMetaXML.DataSource = MetaXML.Tables[0]; 

圖2 - 輸入XML:

<?xml version='1.0'?> 
<records> 
    <record> 
    <recordTypeId>01</recordTypeId> 
    <fields> 
     <field> 
     <fieldNID>entityID</fieldNID> 
     <fieldID>1</fieldID> 
     <fieldName>Entity ID</fieldName> 
     <fieldStartPos>1</fieldStartPos> 
     <fieldEndPos>6</fieldEndPos> 
     <fieldLength>6</fieldLength> 
     <fieldType>Alpha</fieldType> 
     <fieldRequired>Y</fieldRequired> 
     <fieldDefaultValue></fieldDefaultValue> 
     </field> 
     <field> 
     <fieldNID>reserved0101</fieldNID> 
     <fieldID>2</fieldID> 
     <fieldName>Reserved</fieldName> 
     <fieldStartPos>7</fieldStartPos> 
     <fieldEndPos>8</fieldEndPos> 
     <fieldLength>2</fieldLength> 
     <fieldType>Alpha</fieldType> 
     <fieldRequired>Y</fieldRequired> 
     <fieldDefaultValue> </fieldDefaultValue> 
     </field> 
     <field> 
     <fieldNID>deviceID</fieldNID> 
     <fieldID>3</fieldID> 
     <fieldName>Device ID</fieldName> 
     <fieldStartPos>9</fieldStartPos> 
     <fieldEndPos>23</fieldEndPos> 
     <fieldLength>15</fieldLength> 
     <fieldType>Alpha</fieldType> 
     <fieldRequired>Y</fieldRequired> 
     <fieldDefaultValue></fieldDefaultValue> 
     </field> 
    </fields> 
    </record> 
    <record> 
    <recordTypeId>02</recordTypeId> 
    <fields> 
     <field> 
     <fieldNID>userID</fieldNID> 
     <fieldID>1</fieldID> 
     <fieldName>User ID</fieldName> 
     <fieldStartPos>1</fieldStartPos> 
     <fieldEndPos>6</fieldEndPos> 
     <fieldLength>6</fieldLength> 
     <fieldType>Alpha</fieldType> 
     <fieldRequired>Y</fieldRequired> 
     <fieldDefaultValue></fieldDefaultValue> 
     </field> 
     <field> 
     <fieldNID>reserved0201</fieldNID> 
     <fieldID>2</fieldID> 
     <fieldName>Reserved</fieldName> 
     <fieldStartPos>7</fieldStartPos> 
     <fieldEndPos>8</fieldEndPos> 
     <fieldLength>2</fieldLength> 
     <fieldType>Alpha</fieldType> 
     <fieldRequired>Y</fieldRequired> 
     <fieldDefaultValue> </fieldDefaultValue> 
     </field> 
     <field> 
     <fieldNID>testField</fieldNID> 
     <fieldID>3</fieldID> 
     <fieldName>Test Sequence</fieldName> 
     <fieldStartPos>9</fieldStartPos> 
     <fieldEndPos>23</fieldEndPos> 
     <fieldLength>15</fieldLength> 
     <fieldType>Alpha</fieldType> 
     <fieldRequired>Y</fieldRequired> 
     <fieldDefaultValue></fieldDefaultValue> 
     </field> 
    </fields> 
    </record> 
</records> 

圖3 - 輸出XML:

<records> 
    <recordTypeId_x0020_01> 
    <fieldNID>entityID</fieldNID> 
    <fieldID>1</fieldID> 
    <fieldName>Entity ID</fieldName> 
    <fieldStartPos>1</fieldStartPos> 
    <fieldEndPos>6</fieldEndPos> 
    <fieldLength>6</fieldLength> 
    <fieldType>Alpha</fieldType> 
    <fieldRequired>Y</fieldRequired> 
    <fieldDefaultValue /> 
    </recordTypeId_x0020_01> 
    <recordTypeId_x0020_01> 
    <fieldNID>reserved0101</fieldNID> 
    <fieldID>2</fieldID> 
    <fieldName>Reserved</fieldName> 
    <fieldStartPos>7</fieldStartPos> 
    <fieldEndPos>8</fieldEndPos> 
    <fieldLength>2</fieldLength> 
    <fieldType>Alpha</fieldType> 
    <fieldRequired>Y</fieldRequired> 
    <fieldDefaultValue /> 
    </recordTypeId_x0020_01> 
    <recordTypeId_x0020_01> 
    <fieldNID>deviceID</fieldNID> 
    <fieldID>3</fieldID> 
    <fieldName>Device ID</fieldName> 
    <fieldStartPos>9</fieldStartPos> 
    <fieldEndPos>23</fieldEndPos> 
    <fieldLength>15</fieldLength> 
    <fieldType>Alpha</fieldType> 
    <fieldRequired>Y</fieldRequired> 
    <fieldDefaultValue /> 
    </recordTypeId_x0020_01> 
    <recordTypeId_x0020_02> 
    <fieldNID>userID</fieldNID> 
    <fieldID>1</fieldID> 
    <fieldName>User ID</fieldName> 
    <fieldStartPos>1</fieldStartPos> 
    <fieldEndPos>6</fieldEndPos> 
    <fieldLength>6</fieldLength> 
    <fieldType>Alpha</fieldType> 
    <fieldRequired>Y</fieldRequired> 
    <fieldDefaultValue /> 
    </recordTypeId_x0020_02> 
    <recordTypeId_x0020_02> 
    <fieldNID>reserved0201</fieldNID> 
    <fieldID>2</fieldID> 
    <fieldName>Reserved</fieldName> 
    <fieldStartPos>7</fieldStartPos> 
    <fieldEndPos>8</fieldEndPos> 
    <fieldLength>2</fieldLength> 
    <fieldType>Alpha</fieldType> 
    <fieldRequired>Y</fieldRequired> 
    <fieldDefaultValue /> 
    </recordTypeId_x0020_02> 
    <recordTypeId_x0020_02> 
    <fieldNID>testField</fieldNID> 
    <fieldID>3</fieldID> 
    <fieldName>Test Sequence</fieldName> 
    <fieldStartPos>9</fieldStartPos> 
    <fieldEndPos>23</fieldEndPos> 
    <fieldLength>15</fieldLength> 
    <fieldType>Alpha</fieldType> 
    <fieldRequired>Y</fieldRequired> 
    <fieldDefaultValue /> 
    </recordTypeId_x0020_02> 
</records> 

回答

0

結束了K3B的方法去(對不起,不能給予好評 - 需要更多的聲譽)。

下面是更新後的代碼讀取XML到數據集(記住,這只是一個模擬的代碼,使事情的第一次合作。你應該修改它更有效率,並最終更有意義):

int iTableNumber = 1; 

// Read input XML 
using (XmlReader xrMeta = XmlReader.Create(new StreamReader(ofdOpenXML.FileName))) 
{ 
    while (!xrMeta.EOF) 
    { 
    // Advance to next <record> 
    xrMeta.ReadToFollowing("record"); 
    if (xrMeta.NodeType == XmlNodeType.Element) 
    { 
     // Advance to the next <fields> 
     xrMeta.ReadToFollowing("fields"); 

     // Read underlying XML - it will be a set of flat tables 
     xrSub = xrMeta.ReadSubtree(); 
     dt = new DataTable(); 

     ds = new DataSet("fields"); 

     ds.ReadXml(xrSub); 
     dt = ds.Tables[0].Copy(); 

     dt.TableName = "field_" + iTableNumber.ToString().PadLeft(2, '0'); 
     MetaXML.Tables.Add(dt); 
     iTableNumber++; 
     } 
    } 
} 

// Populate comboBox to switch between tables in DataSet 
for (int i = 0; i < MetaXML.Tables.Count; i++) 
{ 
    cbShowTable.Items.Add(MetaXML.Tables[i].TableName); 
} 

// Populate DataGridView with first read table 
dataGridViewMetaXML.DataSource = MetaXML.Tables[0]; 

保存XML現在看起來是這樣的:

 // This is our output XML file 
     // Technically, it should have been the same name as the input one 
     // but for the purposes of testing it isn't 
     StreamWriter srFile = new StreamWriter((@"testingOutputXML.xml")); 
     StringWriter stWriter; 
     StringBuilder sbXML = new StringBuilder(); 

     // Headers to play nice 
     sbXML.AppendLine("<?xml version='1.0'?>"); 
     sbXML.AppendLine("<records>"); 
     DataTable dt; 
     for (int i = 0; i < MetaXML.Tables.Count; i++) 
     { 
      // This is where we have to recreate the structure manually 
      sbXML.AppendLine("<record>"); 
      sbXML.Append("<recordTypeId>"); 
      sbXML.Append((1+ i).ToString().PadLeft(2,'0')); 
      sbXML.AppendLine("</recordTypeId>"); 
      dt = new DataTable(); 
      dt = MetaXML.Tables[i].Copy(); 
      dt.TableName = "field"; 

      stWriter = new StringWriter(); 
      dt.WriteXml(stWriter, false);    
      stWriter.WriteLine(); 

      sbXML.Append(stWriter.GetStringBuilder()); 

      // Need to clean up because DataTable's WriteXML() method 
      // wraps the data in <DocumentElement> and </DocumentElement> tags 
      sbXML.Replace("DocumentElement", "fields"); 
      sbXML.AppendLine("</record>"); 
     } 
     sbXML.AppendLine("</records>"); 
     srFile.Write(sbXML.ToString()); 
     srFile.Flush(); 
     srFile.Close(); 

     MessageBox.Show("Done!"); 

謝謝大家誰與答案插話,它把我領到了正確的軌道上。

0
> The XML I read looks very nice and humanly readable (see fig. 2 below), however, 
> the written XML is nowhere near the original (see fig. 3 below). 
> What am I doing wrong? 

dotnet數據集只能寫入其內部表示的xml格式ñ。 這種表示類似於

<datasetName> 
    <dataTableName OtherFieldName='value'> 
     <FieldName>value</FieldName> 
    </dataTableName> 
    </datasetName> 

所以字段是元件或attributs。你的xml結構更復雜。 如果可能,數據集會嘗試解釋您的數據並將數據放入其內部結構中。在你的例子中,recordTypeId信息丟失。

我也有類似的問題,創造了我自己的XML-後processer是重新格式化XML輸出到我自己的XML的格式,數據集可以讀不能寫。

+0

我希望這是我的錯誤,而不是框架的缺陷:)這種情況的最佳方法是什麼?只需手動構建XML?或者是其他東西? – Vlad

0

你的代碼使用

xrMeta.ReadToFollowing("fields"); 

閱讀下fields條目在每次迭代你再從fields重命名基表recordTypeId XX

dt.TableName = "recordTypeId " + iTableNumber.ToString().PadLeft(2, '0');` 

和空間進行編碼以_x0020_來避免打破標籤。

然後你可以

MetaXML.Tables.Add(dt); 

fields這個改名實例回輸出是這樣的結果。

你試圖達到什麼樣的結果?

+0

我正在嘗試以與閱讀時相同的方式獲取XML。感謝您指出這一點,我會澄清我的問題。 – Vlad

+0

爲什麼不綁定並保存到原始數據集或其克隆?這將允許您在不改變架構的情況下輸出。 –

+0

羅布,你能給我一個例子,說明你的意思是綁定並保存到數據集?不知道什麼被綁定和保存。 – Vlad