2009-11-15 1 views
1

Мой XML документа, как показано ниже -XML Перемещение, копирование элементов и узлов с помощью LINQ к 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"); 

И это отлично работает, без каких-либо проблем. Понятно, что это не хорошее программирование. Потому что я извлекаю Element Parents, а затем использую это как корневой узел, я извлекаю Parent и т. Д.,

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

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

ответ

3

Я бы не сказал, что вы делаете что-то «глупые», но есть способы, чтобы клонировать узел и изменить его в более обтекаемой способом с помощью 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(); 

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

2

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

using System.Xml.XPath; 

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