从嵌套对象到使用递归的XML文档

时间:2018-02-12 12:48:11

标签: c# xml linq recursion nested

我了解提供的建议here

但是我想帮助我理解代码中的错误。

我有一个从这个类派生的对象列表

public class Leaf
{
    public String key { get; set; }
    public String id { get; set; }
    public String value { get; set; }

    public List<Leaf> branch { get; set; } //children

    public Leaf()
    {
        branch = new List<Leaf>();
        key = "";
        id = "";
        value = "";
        parent_id_value = "";
    }

}

主要是我有这些对象:

List<Leaf> tree = new List<Leaf>();
 XElement xmloutput = new XElement("root");

现在,我想通过我的列表及其子代来创建嵌套的XML结构,使用以下规则:

  1. 当Leaf对象没有子节点时,该过程必须创建<dictionaryitem/>元素
  2. 当Leaf有孩子时,程序必须创建一个<dictionarygroup></dictionarygroup>,其中包含子项,这些子项可以是字典组或字典组,具体取决于它们是否有自己的孩子。
  3. dictionaryitem和dictionarygroup都具有相同的属性,派生自Leaf对象。
  4. 我的递归程序如下:

    public static XElement CreateString(List<Leaf> tree, XElement xmloutput)
         {
             XElement xml = null;
             foreach(Leaf lf in tree)
             {
                 if(lf.branch.Count > 0 && lf.branch[0].id!="")
                 {
    
                     xml = new XElement("dictionarygroup",
                         new XAttribute("codeScheme", 1),
                         new XAttribute("codeValue", lf.id),
                         new XAttribute("codeMeaning", lf.value),
                         new XAttribute("codeSchemeVersion", "01"),
                         new XAttribute("isCancelled", "false"),
                         new XElement(CreateString(lf.branch, null))
                         );
    
                 }
                 else
                 {
                     xml = new XElement("dictionaryItem",
                       new XAttribute("codeScheme", 1),
                       new XAttribute("codeValue", lf.id),
                       new XAttribute("codeMeaning", lf.value),
                       new XAttribute("codeSchemeVersion", "01"),
                       new XAttribute("isCancelled", "false")
                       );
                 }
    
                 if (xmloutput != null)
                     xmloutput.Add(xml);
                 else
                     xmloutput = xml;
    
                 xml = null;
             }
    
             return xmloutput;
         }
    

    它产生一个结果,但不是预期结果;我们以此数据为例:

    List<Leaf> tree = new List<Leaf>();
    
            Leaf leaf1 = new Leaf();
            leaf1.key = "L1";
            leaf1.id = "257170";
            leaf1.value = "house";
    
            Leaf leaf2 = new Leaf();
            leaf2.key = "L1";
            leaf2.id = "44444";
            leaf2.value = "mouse";
    
            Leaf leaf1_1 = new Leaf();
            leaf1_1.key = "L2";
            leaf1_1.id = "323233";
            leaf1_1.value = "window";
    
            Leaf leaf1_2 = new Leaf();
            leaf1_2.key = "L2";
            leaf1_2.id = "666666";
            leaf1_2.value = "door";
    
            leaf1.branch.Add(leaf1_1);
            leaf1.branch.Add(leaf1_2);
    
            tree.Add(leaf1);
            tree.Add(leaf2);
    

    我希望得到以下结果:

    <root>
    <dictionarygroup codeScheme="1" codeValue="257170" codeMeaning="house" codeSchemeVersion="01" isCancelled="false">
        <dictionaryItem codeScheme="1" codeValue="323233" codeMeaning="window" codeSchemeVersion="01" isCancelled="false" />
        <dictionaryItem codeScheme="1" codeValue="666666" codeMeaning="door" codeSchemeVersion="01" isCancelled="false" />
    </dictionarygroup>
    <dictionaryItem codeScheme="1" codeValue="44444" codeMeaning="mouse" codeSchemeVersion="01" isCancelled="false" />
    

    相反,我得到了这个:

    <root>
    <dictionarygroup codeScheme="1" codeValue="257170" codeMeaning="house" codeSchemeVersion="01" isCancelled="false">
        <dictionaryItem codeScheme="1" codeValue="323233" codeMeaning="window" codeSchemeVersion="01" isCancelled="false">
            <dictionaryItem codeScheme="1" codeValue="666666" codeMeaning="door" codeSchemeVersion="01" isCancelled="false" />
        </dictionaryItem>
    </dictionarygroup>
    <dictionaryItem codeScheme="1" codeValue="44444" codeMeaning="mouse" codeSchemeVersion="01" isCancelled="false" />
    

    因此,每当有孩子时,第一个被用作包含其他兄弟姐妹的分组标签,因此它就像父母一样。

1 个答案:

答案 0 :(得分:4)

我设法用最少的更改来修复代码。

数据初始化部分:

List<Leaf> tree = new List<Leaf>();

Leaf leaf1 = new Leaf();
leaf1.key = "L1";
leaf1.id = "257170";
leaf1.value = "house";

Leaf leaf2 = new Leaf();
leaf2.key = "L1";
leaf2.id = "44444";
leaf2.value = "mouse";

Leaf leaf1_1 = new Leaf();
leaf1_1.key = "L2";
leaf1_1.id = "323233";
leaf1_1.value = "window";

Leaf leaf1_2 = new Leaf();
leaf1_2.key = "L2";
leaf1_2.id = "666666";
leaf1_2.value = "door";

leaf1.branch.Add(leaf1_1);
leaf1.branch.Add(leaf1_2);

tree.Add(leaf1);
tree.Add(leaf2);

//Create root element
XElement parentElement = new XElement("Root");

var result = CreateCorrectString(tree, parentElement);

CreateString的实现:

public static XElement CreateCorrectString(List<Leaf> tree, XElement parent)
{
    XElement xml = null;
    foreach (Leaf lf in tree)
    {
        if (lf.branch.Count > 0 && lf.branch[0].id != "")
        {
            xml = new XElement("dictionarygroup",
                new XAttribute("codeScheme", 1),
                new XAttribute("codeValue", lf.id),
                new XAttribute("codeMeaning", lf.value),
                new XAttribute("codeSchemeVersion", "01"),
                new XAttribute("isCancelled", "false")
                );

            CreateCorrectString(lf.branch, xml);
        }
        else
        {
            xml = new XElement("dictionaryItem",
                new XAttribute("codeScheme", 1),
                new XAttribute("codeValue", lf.id),
                new XAttribute("codeMeaning", lf.value),
                new XAttribute("codeSchemeVersion", "01"),
                new XAttribute("isCancelled", "false")
                );

        }

        parent.Add(xml);

    }

    return parent;
}

P.S。当然,这不是指定任务的最佳算法,但我尝试尽可能少地更改源代码。