0

我有描述我希望能够编辑的某些数据(模板)的 XML。我将 XML 加载到 DataSet(参见下面的图 1),将 DataSet 表插入 DataGridView(使用单独的组合框在它们之间切换),进行更改,然后保存 XML(简单的 DataSet.WriteXML 指令)。我阅读的 XML 看起来非常漂亮且易于阅读(参见下面的图 2),但是,编写的 XML 与原始 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>
4

3 回答 3

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 后处理器,它将 xml 输出重新格式化为我自己的 xml 格式,数据集可以读取但不能写入。

于 2013-06-25T15:14:09.100 回答
0

fields您的代码正在使用每次迭代读取下一个条目

xrMeta.ReadToFollowing("fields");

然后,您将基表从 重命名fieldsrecordTypeId XX

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

并且空间被编码为 _x0020_ 以避免破坏标签。

然后,您将这个重命名的实例添加回fields目录

MetaXML.Tables.Add(dt);

输出就是这个结果。

你试图达到什么不同的结果?

于 2013-06-25T15:17:06.813 回答
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!");

感谢所有提供答案的人,它引导我走上正确的道路。

于 2013-06-27T13:10:19.687 回答