C # - добавить массив XElement к XElement - PullRequest
0 голосов
/ 23 октября 2018

У меня есть приложение ac #, в котором я сравниваю данные двух XML-файлов внутри метода с именем RevisionTree .Я возвращаю список элементов (XElement) из этого метода.Из метода BuildXml вызовите этот метод и сохраните список как tree .Затем я создаю xml root XElement.Затем я зацикливаюсь на каждом элементе из дерева и добавляю указанных потомков (status, msg, date) к элементу root , каждый из которых является XElement.Так что я должен увидеть XML-документ с root , затем список повторяющихся XML. Тем не менее, когда я пытаюсь сохранить файл в устройстве записи, я получаю следующую ошибку:

Ошибка

Exception thrown: 'System.InvalidOperationException' in System.Private.Xml.dll
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Private.Xml.dll
Token StartDocument in state Document would result in an invalid XML document.

Код

    {
        IEnumerable<XElement>
        var tree = RevisionTree("C:\\Users\\Owner\\source\\repos\\SvnCore\\SvnCore\\old_logs.xml", "C:\\Users\\Owner\\source\\repos\\SvnCore\\SvnCore\\new_logs.xml");

        using (XmlWriter writer = XmlWriter.Create("C:\\Users\\Owner\\source\\repos\\SvnCore\\SvnCore\\Temp.xml", xmlSettings))
        {
            writer.WriteStartDocument();
            var root = new XElement("root");
            foreach (var node in tree)
            {
                root.Add(new XElement("id", node.FirstAttribute));
                root.Add(node.Descendants("status").FirstOrDefault());
                root.Add(node.Descendants("msg").FirstOrDefault());
                root.Add(node.Descendants("date").FirstOrDefault());
            }
            root.Save(writer); 
            writer.WriteEndElement();
            writer.WriteEndDocument();
        }
        return true; 
    }

enter image description here

1 Ответ

0 голосов
/ 24 октября 2018

XElement.Save создает целый документ самостоятельно - вам нужно XElement.WriteTo, чего нет.Поэтому (упрощенно):

var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
using (XmlWriter writer = XmlWriter.Create(sw)) {
    var root = new XElement("root");
    root.Add(new XElement("id", "1"));
    root.Save(writer);  // no DocumentStart, no ElementStart
}
<?xml version="1.0" encoding="utf-16"?><root><id>1</id></root>

или (если вы хотите написать несколько элементов или по какой-то другой причине хотите самостоятельно управлять узлом документа):

using (XmlWriter writer = XmlWriter.Create(sw)) {
    writer.WriteStartDocument();
    writer.WriteStartElement("root");
    var notRoot = new XElement("notRoot");
    notRoot.Add(new XElement("id", "1"));
    notRoot.WriteTo(writer); 
    notRoot.WriteTo(writer);
}
<?xml version="1.0" encoding="utf-16"?><root><notRoot><id>1</id></notRoot><notRoot><id>1</id></notRoot></root>

Обратите внимание, что я опускаю вызовы End, поскольку XmlWriter позаботится об этом неявно.

Если вы не делаете ничего интересного с xmlSettings, весьвсе еще проще, поскольку XElement.Save имеет перегрузку, которая принимает имя файла напрямую, поэтому вам вообще не нужен XmlWriter.

...