English 中文(简体)
XML Traversing, Copy Elements and Nodes using LINQ to XML
原标题:

My XML Document is as below -

<?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>

Requirement -

  1. To identify the Element "Parent", clone it. Change the attribute id to "B". Add it as a sibling to itself (making it a new child of "Parents").
  2. The output file is as below -

    <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>
    

My Code

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");

And it works perfectly fine, without any issues. Clearly, this is no good programming. Because, I am extracting the Element Parents, then using that as a root node, I am extracting Parent etc.,

What I would want to be able to do is something like this - Directly key in the path - as in /Parents/Parent(XPath), extract that particular Node, make a copy of it, make modifications to its attributes, add it as a sibling and save the Document.

Am I doing something silly?

最佳回答

I wouldn t say you re doing something "silly" but there are ways to clone a node and modify it in a more streamlined way with LINQ. Depending on what your goals are, you can use a function to modify the node and some handy LINQ expressions to clone it. Here is an example based on what you ve done above:

        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();

You can see the logic for transforming in the "trans" anonymous function and the ability to arbitrarily select a node using the Descendants enumeration in LINQ. This solution is somewhat brittle but perhaps it can give you some ideas.

问题回答

If you want to use XPath in Linq-to-xml, here are some extension methods that will be help.

using System.Xml.XPath;

XDocument.Load("file name").XPathSelectElement("XPath");




相关问题
Updating Linq to XML element values concatenation issues

I am trying to write a app.config / web.config error correcting app which will audit our developers applications for incorrect environment settings. I am using Linq to XML to accomplish this and I am ...

Is LINQ to XML s XElement ordered?

When I use LINQ to XML, is the order of the elements and attributes written out to text guaranteed to be the same order as how I added the XElement and XAttribute objects? Similarly, when I read in ...

热门标签