优化递归XML构建

时间:2012-12-13 09:19:17

标签: c# xml linq-to-xml

我有一些代码是为了递归地构建XML而编写的,除了一件事之外,它的工作原理非常好,不是那么通用。

数组是

string[] countries= string[]{ ..... }

如果一个数组只包含1个字符串,那么我的想法就是:

<Where>
  <Eq>
    <FieldRef />
    <Value />
  </Eq>
</Where>

如果有多于一个,那么它应该包含<OR>,但是对于最后一个字符串值应该在同一个OR中:所以基本上它就像4个项目那样:

<Where>
  <Or>
    <Eq>
      <FieldRef Name="Title" />
      <Value Type="Text">Canada</Value>
    </Eq>
    <Or>
      <Eq>
        <FieldRef Name="Title" />
        <Value Type="Text">New Zealand</Value>
      </Eq>
      <Or>
        <Eq>
          <FieldRef Name="Title" />
          <Value Type="Text">United States</Value>
        </Eq>
        <Eq>
          <FieldRef Name="Title" />
          <Value Type="Text">Switzerland</Value>
        </Eq>
      </Or>
    </Or>
  </Or>
</Where>

一切都是嵌套的。

这是我的代码,它适用于多数组,但不适用于单个结果:

private XElement Recursion(XElement parentElement, int counter)

    {
        if (counter == 0)
        { 
            return parentElement;
        }

        XElement orElement = new XElement("Or");
        XElement eqElement = new XElement("Eq");

        XElement fieldElement = new XElement("FieldRef");
        XAttribute nameAttribute = new XAttribute("Name", "Title");
        fieldElement.Add(nameAttribute);

        XElement valueElement = new XElement("Value", Countries[counter]);
        XAttribute typeAttribute = new XAttribute("Type", "Text");
        valueElement.Add(typeAttribute);

        eqElement.Add(fieldElement);
        eqElement.Add(valueElement);

        orElement.Add(eqElement);

        if (counter == 1)
        {
            eqElement = new XElement("Eq");
            valueElement = new XElement("Value", Countries[0]);
            valueElement.Add(typeAttribute);

            eqElement.Add(fieldElement);
            eqElement.Add(valueElement);

            orElement.Add(eqElement);
        }

         XElement lastOrElement = parentElement.Descendants("Or").FirstOrDefault(or => !or.Descendants("Or").Any());
        if (lastOrElement == null)
        {
            parentElement.Add(orElement);
        }
        else
        {
            lastOrElement.Add(orElement);
        }

        return Recursion(parentElement, --counter);
    }
}

1 个答案:

答案 0 :(得分:0)

如果第一次进入函数,则需要测试counter何时为1。

可能最简单的方法是更改​​你的if (counter==1)块以测试传递的父元素是否为空(或者不包含任何其他<OR>元素(不清楚首先如何调用此函数以及何时<where>元素已添加。

尝试类似:

if (counter == 1)
{
    if (!parentElement.Descendant("Or").Any())
    {
        //Single array case
        return eqElement;
    }

    // Not single array case, code as before....
    eqElement = new XElement("Eq");
    ...