2008-10-16 9 views
49

मैं एक LINQ की एक्सएमएल XElement की गहरी प्रतिलिपि बनाना चाहता हूं। कारण मैं यह करना चाहता हूं कि दस्तावेज़ में कुछ नोड्स हैं जिन्हें मैं संशोधित प्रतियां (उसी दस्तावेज़ में) बनाना चाहता हूं। मुझे ऐसा करने का कोई तरीका नहीं दिख रहा है।मैं LINQ से XML में किसी तत्व की गहरी प्रति कैसे करूं?

मैं तत्व को XML स्ट्रिंग में परिवर्तित कर सकता हूं और फिर इसे दोबारा बदल सकता हूं, लेकिन मुझे आश्चर्य है कि कोई बेहतर तरीका है या नहीं।

+0

डैनियल - मुझे लगता है कि आपको इस प्रश्न के स्वीकृत उत्तर पर पुनर्विचार करना चाहिए। –

+0

हो गया- मैंने स्वीकृत उत्तर बदल दिया। –

उत्तर

98

पुनर्भुगतान की कोई आवश्यकता नहीं है। XElement के निर्माताओं में से एक एक और XElement लेता है और यह की एक गहरी प्रतिलिपि बनाता है:

[TestMethod] 
public void XElementShallowCopyShouldOnlyCopyReference() 
{ 
    XElement original = new XElement("original"); 
    XElement shallowCopy = original; 
    shallowCopy.Name = "copy"; 
    Assert.AreEqual("copy", original.Name); 
} 

[TestMethod] 
public void ShouldGetXElementDeepCopyUsingConstructorArgument() 
{ 
    XElement original = new XElement("original"); 
    XElement deepCopy = new XElement(original); 
    deepCopy.Name = "copy"; 
    Assert.AreEqual("original", original.Name); 
    Assert.AreEqual("copy", deepCopy.Name); 
} 
+0

+1: * यह * पोस्ट स्वीकृत उत्तर होना चाहिए। परीक्षण विधियों के लिए –

+0

+1। –

+2

मेरा मानना ​​है कि इस उदाहरण में प्रयुक्त कन्स्ट्रक्टर सामान्य रूप से ** कॉपी कन्स्ट्रक्टर ** के रूप में जाना जाता है। ['XElement' कॉपी कन्स्ट्रक्टर] (http://msdn.microsoft.com/en-us/library/bb297950%28v=vs.110%29.aspx) के लिए दस्तावेज़ यहां दिया गया है। एक ['XDocument' कॉपी कन्स्ट्रक्टर] भी है (http://msdn.microsoft.com/en-us/library/bb341301%28v=vs.110%29.aspx)। सौभाग्य से हमारे लिए, ** LINQ से XML ** यह आसान बनाता है ... सामान्य रूप से, [गहरी प्रतिलिपि (या क्लोनिंग)] (http://stackoverflow.com/questions/78536/deep-cloning-objects-in-c -शर्प) कई बार इतना सरल नहीं हो सकता है। – DavidRR

-2

मुझे विश्वास नहीं है कि एक मौजूदा तंत्र है जो आपको XNode शैली के पेड़ की गहरी प्रतिलिपि करने की अनुमति देता है। मुझे लगता है कि आप दो विकल्पों के साथ छोड़ दिया गया है।

  1. के रूप में आप एक परिवर्तित एक स्ट्रिंग के लिए सुझाव दिया वापस एक पेड़ से अपने आप पर
  2. लिख सकता हूँ और फिर एक आगंतुक पैटर्न

आगंतुक पैटर्न निश्चित रूप से संभव है के साथ है, लेकिन यह एक अच्छा सौदा ले जाएगा एक परीक्षण का काम। मुझे लगता है कि आपका सबसे अच्छा विकल्प # 1 है।

6

ऐसा लगता है कि ToString और reparse विधि सबसे अच्छा तरीका है।

XElement copy = XElement.Parse(original.ToString()); 
+0

फिर DstNode.Add (कॉपी) इसे जोड़ने के लिए जोड़ें। किया हुआ। – Fraga

2

C# 3.0 in a Nutshell से सीधे लिफ़्टेड:

एक नोड या विशेषता नोड या विशेषता के जनक संपत्ति पर सेट है (कार्यात्मक निर्माण या एक विधि जोड़ें के द्वारा) एक तत्व में जोड़ा जाता है यहाँ कोड है वह तत्व एक नोड में केवल एक मूल तत्व हो सकता है: यदि आप पहले से ही अभिभावक नोड को दूसरे माता-पिता में जोड़ते हैं, तो नोड स्वचालित रूप से गहरा क्लोन होता है।

var address = new XElement ("address", 
        new XElement ("street", "Lawley St"), 
        new XElement ("town", "North Beach") 
      ); 
var customer1 = new XElement ("customer1", address); 
var customer2 = new XElement ("customer2", address); 

customer1.Element ("address").Element ("street").Value = "Another St"; 
Console.WriteLine (
    customer2.Element ("address").Element ("street").Value); // Lawley St 

यह स्वत: दोहराव एक्स डोम वस्तु इन्स्टेन्शियशन दुष्प्रभाव-एक और कार्यात्मक प्रोग्रामिंग की पहचान से मुक्त रखता है: निम्न उदाहरण में, प्रत्येक ग्राहक के पते की एक अलग कॉपी है।

+3

इसे स्वीकृत उत्तर के रूप में क्यों चिह्नित किया गया है? –

0

यह काम करना चाहिए:

var copy = new XElement(original.Name, original.Attributes(), 
         original.Elements()); 

XElement original = new XElement("original"); 
XElement deepCopy = new XElement(original); 

यहाँ इकाई परीक्षण के एक जोड़े को प्रदर्शित कर रहे हैं

संबंधित मुद्दे