Динамическое построение XML-дерева во время выполнения с использованием linq - PullRequest
0 голосов
/ 08 ноября 2010

Это вопрос дизайна, чтобы разжечь аппетит гуру.

В предыдущей версии код использовал определение пути, т. Е. /../../, чтобы предоставить инструкции по созданию artbitary XML-документов.Документы должны были быть правильными в соответствии со схемой xml, поэтому пути были по существу xpaths, которые читались и использовались в выражениях switch для вызова кода для создания документа.Но не зацикливайтесь на этом.

Например, вызов при чтении и кодировании

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 to xsd, чтобы создать дерево xml, но я все еще ищу какой-то конструкт, который позволит пользователю определить, как будет построено дерево.XPath легки, но довольно громоздки в реализации, не элегантны, и я не так легко картирую.

Будут оценены любые идеи, любые программы, открытый исходный код, исследования, все, что угодно.Если я не получу ответ, я предложу достойную награду через 3 дня.Боб.

1 Ответ

1 голос
/ 09 ноября 2010

Как насчет того, чтобы сделать что-то вроде этого:

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);
}
...