Обход XML, копирование элементов и узлов с использованием LINQ to XML - PullRequest
1 голос
/ 15 ноября 2009

Мой XML-документ выглядит так -

<?xml version="1.0" encoding="utf-8"?>
<Parents>
    <Parent id="A" description="A is a parent">
        <Children>
            <ChildName name = "Son1ofA" />
            <ChildName name = "Son2ofA" />
        </Children>
    </Parent>
</Parents>

Требование -

  1. Чтобы идентифицировать Элемент «Родитель», клонируйте его. Измените идентификатор атрибута на «B». Добавьте это как родного брата к себе (делая его новым ребенком "Родителей").
  2. Выходной файл, как показано ниже -

    <Parents>
    <Parent id="A" description="A is a parent">
        <Children>
            <ChildName name = "Son" />
            <ChildName name = "Daughter" />
        </Children>
    </Parent>
    <Parent id="B" description="A is a parent">
        <Children>
            <ChildName name = "Son" />
            <ChildName name = "Daughter" />
        </Children>
    </Parent>
    

Мой код

XDocument myXMLDocument = XDocument.Load("File.xml");
XElement myParentsElement = myXMLDocument.Element("Parents");
XElement myFirstParentElement = myParentsElement.Element("Parent");
XElement myNewParentElement = new XElement(myFirstParentElement);
XAttribute myParentId = myNewParentElement.Attribute("id");
myParentId.Value = "B";
myFirstParentElement.AddAfterSelf(myNewParentElement);
myXMLDocument.Save("NewFile.xml");

И все работает отлично, без проблем. Понятно, что это плохое программирование. Потому что я извлекаю Родителя Элемента, затем использую его как корневой узел, извлекаю Родителя и т. Д.,

То, что я хотел бы сделать, это что-то вроде этого - Непосредственно введите путь - как в / Parents / Parent (XPath), извлеките этот конкретный узел, сделайте его копию, внесите изменения в его атрибуты, добавьте его в качестве родственного элемента и сохраните документ.

Я что-то делаю глупо?

Ответы [ 2 ]

3 голосов
/ 15 ноября 2009

Я бы не сказал, что вы делаете что-то «глупое», но есть способы клонировать узел и изменить его более упорядоченным способом с помощью LINQ. В зависимости от ваших целей, вы можете использовать функцию для изменения узла и некоторые удобные выражения LINQ для его клонирования. Вот пример, основанный на том, что вы сделали выше:

        XDocument doc = XDocument.Parse(@"<?xml version='1.0' encoding='utf-8'?>
        <Parents>
            <Parent id='A' description='A is a parent'>
                    <Children>
                            <ChildName name = 'Son1ofA' />
                            <ChildName name = 'Son2ofA' />
                    </Children>
            </Parent>
        </Parents>
        ");

        Func<XElement, XElement> trans = (x) => {
            char c = Convert.ToChar(x.Attribute("id").Value);
            int inc = (int)c;
            x.Attribute("id").Value = Convert.ToChar(++inc).ToString();
            return x;
        };
        string elementTarget = "Parent"; // assume you read this from some input
        doc.Root.ReplaceWith(new XElement(doc.Root.Name,
                                doc.Descendants(elementTarget).Select(p => p),
                                doc.Descendants(elementTarget).Select(p => trans(p))));

        Console.Write(doc);
        Console.ReadLine();

Вы можете увидеть логику преобразования в анонимной функции «trans» и возможность произвольного выбора узла с помощью перечисления Потомки в LINQ. Это решение несколько хрупкое, но, возможно, оно может дать вам некоторые идеи.

2 голосов
/ 15 ноября 2009

Если вы хотите использовать XPath в Linq-to-xml, вот несколько методов расширения, которые вам помогут.

using System.Xml.XPath;

XDocument.Load("file name").XPathSelectElement("XPath");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...