我有XML描述了我想要编辑的某些数据(模板)。我将XML加载到DataSet中(参见下面的图1),将DataSet表插入DataGridView(使用单独的comboBox在它们之间切换),进行更改然后保存XML(简单的DataSet.WriteXML指令)。我读过的XML看起来非常好看并且具有人性化的可读性(参见下面的图2),然而,书面的XML远不及原版(见下面的图3)。
我的目标是允许编辑XML文档并在保存时以相同的形式保存它。
我做错了什么?代码/ XML块如下所示。
图1 - 将XML读入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];
图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 :(得分: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>
所以字段是元素或属性。你的xml结构更复杂。 如果可能,数据集会尝试解释您的数据并将数据放入其内部结构中。在您的示例中,信息recordTypeId将丢失。
我遇到了类似的问题并创建了一个我自己的xml-post-processer,它将xml-output重新格式化为我自己的xml格式,数据集可以读取但不能写入。
答案 1 :(得分:0)
您的代码正在使用
每次迭代读取下一个fields
条目
xrMeta.ReadToFollowing("fields");
然后,您使用
将基表从fields
重命名为recordTypeId XX
dt.TableName = "recordTypeId " + iTableNumber.ToString().PadLeft(2, '0');`
并且空间被编码为_x0020_以避免破坏标记。
然后,将此重命名的fields
实例添加回 root
MetaXML.Tables.Add(dt);
输出结果就是这样。
你想要达到什么不同的结果?
答案 2 :(得分:0)
结束k3b的方法(对不起,不能投票 - 需要更多的声誉)。
这是将XML读入DataSet的更新代码(请记住,它只是一个模拟代码,可以让事情第一次起作用。你应该修改它以提高效率并最终更有意义):
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!");
感谢所有插入答案的人,它引导我走上了正确的轨道。