使用linq在运行时动态构建xml树

时间:2010-11-08 17:29:28

标签: xml linq c#-4.0 linq-to-xml

这是一个设计问题,以激发大师的胃口。

在以前的版本中,代码使用路径定义,即/../../来提供有关如何构建artbitary xml文档的说明。根据xml模式,文档必须是正确的,因此路径基本上是xpath,在switch语句中读取和使用以调用代码来构造doc。但不要挂断它。

例如,在读入和编码时调用

jim.set("/Alert/Source/DetectTime", "12:03:2010 12:22:21");

会创建

<Alert> 
  <Source>
    <DetectTime>12:03:2010 12:22:21</DetectTime>
  </Source>
</Alert>

jim.set只将树存储在特定的上下文中。

现在我想使用linq到xsd来创建xml树,但我仍然在寻找一些能让用户定义如何构造树的contruct。 XPath很简单,但实现起来有点笨重,不优雅,我不容易映射。

任何想法,任何程序,开源,研究,任何东西都会被贬低。如果我没有得到答案,我将在3天内提供体面的赏金。 鲍勃。

1 个答案:

答案 0 :(得分:1)

做这样的事情怎么样:

public XDocument CreateXDocument(string path, string value)
{
    var parts = path.Split(new [] { '/', },
        StringSplitOptions.RemoveEmptyEntries);
    return new XDocument(this.CreateXElement(parts, value));
}

private XElement CreateXElement(IEnumerable<string> parts, string value)
{
    var content = parts.Count() == 1 ?
        (object)value :
        (object)this.CreateXElement(parts.Skip(1), value);
    return new XElement(parts.First(), content);
}

然后您可以运行如下代码:

var xd = this.CreateXDocument("/Alert/Source/DetectTime", "12:03:2010 12:22:21");
Console.WriteLine(xd.ToString());

将产生:

<Alert>
  <Source>
    <DetectTime>12:03:2010 12:22:21</DetectTime>
  </Source>
</Alert>

我想我可能会发布一个应该更具可读性的CreateXElement方法的变体。功能相同,甚至可能会有很小的性能提升。

private XElement CreateXElement(IEnumerable<string> parts, string value)
{
    var head = parts.First();
    var tail = parts.Skip(1);
    var content = tail.Any() ?
        (object)this.CreateXElement(tail, value) :
        (object)value;
    return new XElement(head, content);
}