如何将XElements动态添加到XML文件?

时间:2016-04-26 01:52:42

标签: c# linq-to-xml xelement dynamic-controls

好的,所以我的程序将保存用户在运行时从NumericUpDown控件中提供的任意数量的XElements。我用XMLtextWriter写这个的方式如下:

public void XMLWriteNewL4Module()
    {
        int i;
        String workingDir = Directory.GetCurrentDirectory();
        //create a new file in the working directory
        XmlTextWriter textWriter = new XmlTextWriter("Level4Modules.xml", null);
        //opens the document
        textWriter.WriteStartDocument();                                      //Document Start
        //first student
        textWriter.WriteStartElement("Module");                                //Module start
        //Module title element
        textWriter.WriteStartElement("Title", "");                                //Title start
        textWriter.WriteString(this.textBoxModuleTitle.Text);
        textWriter.WriteEndElement();                                             //Title end
        //Module code element
        textWriter.WriteStartElement("Code", "");                                 //Code start
        textWriter.WriteString(this.textBoxModuleCode.Text);
        textWriter.WriteEndElement();                                             //Code end
        //Credit value element
        textWriter.WriteStartElement("Credit Value", "");                         //Credit value start
        textWriter.WriteString(this.textBoxModuleCreditValue.Text);
        textWriter.WriteEndElement();                                             //Credit value end 
        //Assessments element
        textWriter.WriteStartElement("Assessments", "");                          //Assessments start
        for (i = 0; i < numericUpDownNoOfAssessments.Value; i++)
        {
            textWriter.WriteStartElement("Assessment", "");                             //Assessment start
            textWriter.WriteStartElement("Assessment Type", "");                        //Assessment type start
            textWriter.WriteString((comboBoxAssessments[i] as ComboBox).Text);
            textWriter.WriteEndElement();                                               //Assessment type end 
            textWriter.WriteStartElement("Assessment Grade", "");                       //Assessment grade start
            textWriter.WriteString((textBoxAssessments[i] as TextBox).Text);
            textWriter.WriteEndElement();                                               //Assessment grade end 
            textWriter.WriteStartElement("Assessment Weighting", "");                   //Assessment weighting start
            textWriter.WriteString((assessmentWeightingTextBox[i] as TextBox).Text);
            textWriter.WriteEndElement();                                               //Assessment weighting end 
            textWriter.WriteEndElement();                                               //Assessment end 
        }
        textWriter.WriteEndElement();                                             //Assessments end 
        textWriter.WriteEndElement();                                          //Module end
        //end the document
        textWriter.WriteEndDocument();                                        //Document end
        //close the writer
        textWriter.Close();
        Console.ReadLine();
    }

但是这种方式不允许我附加XML文件,所以我尝试这样写:

public void XMLWriteNewL4Module()
    {
        String workingDir = Directory.GetCurrentDirectory();
        int i;
        if (File.Exists(workingDir + @"Level4Modules.xml") == false)
        {
            //create a new file in the working directory
            XmlTextWriter textWriter = new XmlTextWriter("Level4Modules.xml", null);
            textWriter.WriteStartElement("Modules");
            textWriter.WriteEndElement();
            textWriter.Close();
        }


        XElement xDoc = XElement.Load(workingDir + @"Level4Modules.xml");
        xDoc.Add(
        new XElement("Module",
            new XElement("Title", this.textBoxStudentFirstName.Text),
            new XElement("Code", this.textBoxStudentSurname.Text),
            new XElement("Credit Value", this.textBoxStudentIDNewUser.Text),
            new XElement("Assessments", 
            for (i = 0; i < numericUpDownNoOfAssessments.Value; i++)
            {
                new XElement("Assessment Type", (comboBoxAssessments[i] as ComboBox).Text),
                new XElement("Assessment Grade",),
                new XElement("Assessment Weighting",))
            }
        ));
        xDoc.Save(workingDir + @"\Students.xml");

    }

并且这不允许我在新的XElement声明中使用for循环(这是可以理解的)所以我需要一个解决它的方法因为我绝对难倒。它显示的错误消息显示“无效的表达式术语”,因为很明显c#不喜欢你在XElement中启动for循环。 我有什么想法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

您可以将for循环放入一个返回XElement []的新方法,并调用需要子项的方法。 像这样:

C#

new XElement("Module",
            new XElement("Title", this.textBoxStudentFirstName.Text),
            new XElement("Code", this.textBoxStudentSurname.Text),
            new XElement("Credit Value", this.textBoxStudentIDNewUser.Text),
            new XElement("Assessments", GetAssessments())); //the returned items will be added as child items to the "Assessments" node

C#

XElement[] GetAssessments()
{
    var result = new List<XElement>();
    for (int i = 0; i < numericUpDownNoOfAssessments.Value; i++)
    {
        result.Add(new XElement("Assessment Type", (comboBoxAssessments[i] as ComboBox).Text));
        result.Add(new XElement("Assessment Grade", ""));
        result.Add(new XElement("Assessment Weighting", ""));
    }
    return result.ToArray();
}

如果有某些上下文信息,您可以将其作为参数传递给新方法。 我希望我能提供帮助。

答案 1 :(得分:0)

您可以使用Enumerable.Range扩展名,这可以让您在XElement内构建嵌套元素。

public void XMLWriteNewL4Module()
{

    String workingDir = Directory.GetCurrentDirectory();
    int i;
    if (File.Exists(workingDir + @"Level4Modules.xml") == false)
    {
        //create a new file in the working directory
        XmlTextWriter textWriter = new XmlTextWriter("Level4Modules.xml", null);
        textWriter.WriteStartElement("Modules");
        textWriter.WriteEndElement();
        textWriter.Close();
    }


    XElement xDoc = XElement.Load(workingDir + @"Level4Modules.xml");
    xDoc.Add(
    new XElement("Module",
        new XElement("Title", this.textBoxStudentFirstName.Text),
        new XElement("Code", this.textBoxStudentSurname.Text),
        new XElement("Credit Value", this.textBoxStudentIDNewUser.Text),
        new XElement("Assessments", Enumerable.Range(0,numericUpDownNoOfAssessments.Value)
                     .Select(i=>
                     {   
                         return new XElement[] {
                            new XElement("Assessment Type", (comboBoxAssessments[i] as ComboBox).Text),
                            new XElement("Assessment Grade"),
                            new XElement("Assessment Weighting")
                         };

                     }))));   

    xDoc.Save(workingDir + @"\Students.xml");
}