【问题标题】:Generic way of creating XML files in C#在 C# 中创建 XML 文件的通用方法
【发布时间】:2013-04-29 17:04:07
【问题描述】:

我正在尝试创建一个使用 LINQ 和 Genertics 保存/读取多个 XML 文件的类。

我正在寻找保存多种类型的 XMl 文件(即其中的数据)的通用方法

每个 XML 文件都有以下格式

<ROOT>
     <!-- First Element/First Row -->
     <NODE>
           <COL1>Some value</COL1>
           .....  
           <COLn>Some value</COLn>
     </NODE>
     .........
     <!-- Nth Element = nth row -->
     <NODE>
           <COL1>Some value</COL1>
           .....  
           <COLn>Some value</COLn>
     </NODE>
</ROOT>

每个文件都有不同的 ROOT、NODE 和 COLx。列数和其中的数据取决于 Multi-Dim 数组输入。这个输入数组还给出了 xml 中节点标签的数量(数组中的元素)。

保存 XML 文件的方法如下所示

public void SaveFirstXmlFile()
{
    XElement xdoc = new XElement("ThisDocsRoot");
    //Iterate for number of rows(elements of data)            
    for (int nodes= 1; nodes<= NUMBER_OF_NODES; nodes++)
    {
        xdoc.Add(new XElement(row,
                              new XElement("Col 1", "Some Value"),
                              new XElement("Col 2", "Some Value"),
                              new XElement("Col 3", "Some Value")
                     ));
    } 
    xdoc.Save("/Path/To/XML/File");
}

我想调整这个方法,使其适用于多个 XML 文件。我不知道这是否是正确的做法,但我计划创建定义 XML 的根、节点、列和路径的类文件。并且数据来自其他一些类创建的Multi-Dim Arrays。

private class AClassforSomeXMLFile
{
    private readonly String _root;
    private readonly String _row;
    private readonly String[] _columns;
    private readonly String _exportPath;

    public UsageData()
    {

        _exportPath = string.Format(@"{0}\xyz.xml",Path.GetDirectoryName(Application.ExecutablePath));

        _root = "ROOT";
        _row = "NODE";
        _columns = new string[]
            {
                "COL1","COL2", "COL3","COL4",
            };
    }

    public string ROOT {  get { return _root; } }

    public string ROW { get { return _row; } }

    public string[] COLS  { get { return _columns; }}

    public string EPATH { get { return _exportPath; }}
}

【问题讨论】:

  • 我不明白这需要泛型——只需将SaveFirstXmlFile 中的文字替换为AClassforSomeXMLFile 中的值?
  • 我知道,但这仅适用于一类,而且我至少要制作 5 种不同类型的 XML 文件。我想要一种适用于所有这些的方法。
  • 你能再举一个你想要制作的另一种xml文件的例子吗?目前还不是很清楚这些 xml 文件之间有什么区别。是不是只有节点的名字,比如ROOT可以变成AAA,NODE可以变成ITEM等等?还是xml结构不同?
  • 如果您对格式有任何控制权,请将 COL1-COLn 替换为一系列 COL 元素,使用 XML 序列化解决它变得微不足道。
  • @Alexander XML 文件之间的区别在于元素,即根名称、节点名称和列数。请参阅我对 Sam 的评论。

标签: c# .net xml linq generics


【解决方案1】:

您可以将构造函数添加到 AClassforSomeXMLFile 类,以填充根、行和列值,然后将定义实例传递给您的 SaveFirstXmlFile 函数:

private class XmlDefinition
{
    public string ROOT { get;set; }
    public string ROW { get;set; }
    public string[] COLS  { get;set; }
    public string EPATH { get;set; }
}


void Foo()
{
  var employeeDefinition = new XmlDefinition 
  { 
    ROOT = "Employees", 
    ROW = "Employee", 
    COLS = new[] { "Name", "Address", "Department", "Salary" },
    EPATH = string.Format(@"{0}\employee.xml",Path.GetDirectoryName(Application.ExecutablePath))
  };

  SaveFirstXmlFile(employeeDefinition); //save employees

  var productDefinition = new XmlDefinition 
  { 
    ROOT = "Products", 
    ROW = "Product", 
    COLS = new[] { "Name", "Description", "Cost" },
    EPATH = string.Format(@"{0}\products.xml",Path.GetDirectoryName(Application.ExecutablePath))
  };

  SaveFirstXmlFile(productDefinition); //save products
}

public void SaveFirstXmlFile(AClassforSomeXMLFile definition)
{
    XElement xdoc = new XElement(definition.ROOT);
    //Iterate for number of rows(elements of data)            
    for (int nodes = 1; nodes <= NUMBER_OF_NODES; nodes++)
    {
        var cols = from c in definition.COLS select new XElement(c, "Some Value");
        xdoc.Add(new XElement(definition.ROW, cols.ToArray()));
    } 
    xdoc.Save(definition.EPATH);
}

【讨论】:

  • 定义的类型怎么样。它是上面的 AClassforSomeXMLFile,但对于不同的 XML 文件它可以不同,所以第一个选项是使用 2 个参数一个 Enum(表示 XML 的类)和类型 Object 的定义。对象将被解析为其类型,例如 AClassforSomeXMLFile 在这种情况下基于枚举。有没有其他更通用的方法可以做到这一点,即我没有强制转换类型或使用枚举等
  • 扩大了我的样本。您不需要多个类 - 一个就足够了(我将其重命名为 XmlDefinition)。您可以在类构造函数中指定所需的名称,然后将相同类型但具有不同内容的内容传递给您的“保存”方法。作为此解决方案的扩展,并且为了节省输入,您可以派生自定义的“ProductXmlDefinition”、“EmployeeXmlDefinition”类,它们在构造函数中进行初始化,并且您可以创建新实例,并在不填充数据的情况下传递它。方法仍将接受基类类型 XmlDefinition。
【解决方案2】:

我不完全理解这里的问题,但是如果您像这样格式化您的 XML 看起来可能会很满意

 <NODE>
       <COL>Some value</COL>
       .....  
       <COL>Some value</COL>
 </NODE>

然后你可以将你所有的COLs 读入一个列表

XElement xdoc = new XElement("ThisDocsRoot");
List<XElement> Cols = xdoc.Elements("COL").ToList();

【讨论】:

  • ROOT 元素、节点元素和列会有所不同。它类似于数据库中的不同表。例如,如果我用 XML 表示员工,我将把根作为员工(表名称),每个节点作为员工(表中的每一行),将 COL 作为名称、地址、部门、工资等(表中的列)。同样,我可以有其他 XML 文件来表示客户、产品等。我希望你理解我打算在我的 XML 文件中做的事情。如果我是正确的,您正在从 XML 创建和列出,但我已将其写入 XML。
  • @KhurramMajeed Descendants() 方法可能会帮助你
猜你喜欢
  • 2011-08-18
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多