C#DataSet XML加载和保存 [英] C# DataSet XML loading and saving
问题描述
我的目标是允许编辑XML文档并保存在保存的相同形式。
我做错了什么?代码/ XML块如下。
fig.1 - 将XML读入DataSet:
code> 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];
fig.2 - 输入XML:
<?xml version ='1.0'?>
< records>
< record>
< recordTypeId> 01< / recordTypeId>
< fields>
< field>
< fieldNID> entityID< / fieldNID>
< fieldID> 1< / fieldID>
< fieldName>实体ID< / fieldName>
< fieldStartPos> 1< / fieldStartPos>
< fieldEndPos> 6< / fieldEndPos>
< fieldLength> 6< / fieldLength>
< fieldType> Alpha< / fieldType>
< fieldRequired> Y< / fieldRequired>
< fieldDefaultValue>< / fieldDefaultValue>
< / field>
< field>
< fieldNID>保留0101< / fieldNID>
< fieldID> 2< / fieldID>
< fieldName>保留< / 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>设备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>用户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>保留< / 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>测试序列< / fieldName>
< fieldStartPos> 9< / fieldStartPos>
< fieldEndPos> 23< / fieldEndPos>
< fieldLength> 15< / fieldLength>
< fieldType> Alpha< / fieldType>
< fieldRequired> Y< / fieldRequired>
< fieldDefaultValue>< / fieldDefaultValue>
< / field>
< / fields>
< / record>
< / records>
fig.3 - 输出XML:
< records>
< recordTypeId_x0020_01>
< fieldNID> entityID< / fieldNID>
< fieldID> 1< / fieldID>
< fieldName>实体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>保留< / 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>设备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>用户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>保留< / 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>测试序列< / fieldName>
< fieldStartPos> 9< / fieldStartPos>
< fieldEndPos> 23< / fieldEndPos>
< fieldLength> 15< / fieldLength>
< fieldType> Alpha< / fieldType>
< fieldRequired> Y< / fieldRequired>
< fieldDefaultValue />
< / recordTypeId_x0020_02>
< / records>
结束了k3b的做法(对不起,
以下是将XML读取到DataSet中的更新代码(请记住,这只是一个模拟代码,使事情能够第一次工作时间,你应该修改它更有效率,最终更有意义):
int iTableNumber = 1;
//读取输入XML
使用(XmlReader xrMeta = XmlReader.Create(new StreamReader(ofdOpenXML.FileName)))
{
while(!xrMeta.EOF )
{
//提前到下一个< record>
xrMeta.ReadToFollowing(record);
if(xrMeta.NodeType == XmlNodeType.Element)
{
//提前到下一个< fields>
xrMeta.ReadToFollowing(fields);
//读底层XML - 它将是一组平面表
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 ++;
}
}
}
//填充comboBox以在DataSet
之间切换(int i = 0; i< MetaXML.Tables .Count; i ++)
{
cbShowTable.Items.Add(MetaXML.Tables [i] .TableName);
}
//使用第一个读表填充DataGridView
dataGridViewMetaXML.DataSource = MetaXML.Tables [0];
保存XML现在如下所示:
//这是我们的输出XML文件
//从技术上来说,它应该是输入一个
//的名称,但是为了测试它不是
StreamWriter srFile = new StreamWriter((@testingOutputXML.xml));
StringWriter stWriter;
StringBuilder sbXML = new StringBuilder();
//标题播放不错
sbXML.AppendLine(<?xml version ='1.0'?>);
sbXML.AppendLine(< records>);
DataTable dt; (int i = 0; i< MetaXML.Tables.Count; i ++)
{
//这是我们必须手动重新创建结构的地方
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());
//需要清理,因为DataTable的WriteXML()方法
//将数据放在< DocumentElement>和< / DocumentElement>标签
sbXML.Replace(DocumentElement,fields);
sbXML.AppendLine(< / record>);
}
sbXML.AppendLine(< / records>);
srFile.Write(sbXML.ToString());
srFile.Flush();
srFile.Close();
MessageBox.Show(Done!);
感谢所有遇到问题的人,它引导我走上正轨。
I've got XML that describes certain data (a template) that I want to be able to edit. I load XML into DataSet (see fig. 1 below), plug DataSet tables into DataGridView (switch between them using a separate comboBox), make changes and then save XML (simple DataSet.WriteXML directive). 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).
My goal is to allow editing of XML document and preserve it in the same form on save.
What am I doing wrong? Code/XML blocks are below.
fig.1 - Reading XML into DataSet:
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];
fig.2 - Input 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>
fig.3 - output 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>
Ended up going with k3b's approach (sorry, can't upvote - need more reputation).
Here's the updated code to read the XML into DataSet (keep in mind, it's just a mock code to make things work for the first time. You should revise it to be more efficient and ultimately make more sense):
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];
Saving XML now looks like this:
// 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!");
Thanks everyone who chipped in with the answers, it steered me to the right track.
这篇关于C#DataSet XML加载和保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!