2011-01-23 6 views
10

मेरे पास डिस्क पर एक बहुत ही बुनियादी एक्सएमएल संरचना/फ़ाइल है जो कुछ है:सी # में, डिस्क पर किसी फ़ाइल को एक्सएमएल नोड जोड़ने के बिना पहले इसे लोड करने का कोई तरीका है?

<root> 
    <data timestamp="dd-mm-yyyy" type="comment">kdkdkdk</data> 
    <data timestamp="dd-mm-yyyy" type="event">kdkdkdkgffgfdgf</data> 
    <data timestamp="dd-mm-yyyy" type="something">kddsdsfsdkdkdk</data> 
</root> 

एक्सएमएल डिस्क पर बाहरी फाइल में उल्लेखित होगा। चूंकि फ़ाइल काफी बड़ी हो सकती है (वास्तव में हर हफ्ते में 'छंटनी' होती है), मैं एक नया नोड जोड़ने के लिए पहले एक्सएमएल फ़ाइल लोड नहीं करना चाहता ...

क्या नया जोड़ने का कोई तरीका है इस तरह नोड? इसे अभी शीर्ष/नीचे इत्यादि में जोड़ा जा सकता है, क्योंकि वास्तव में एक्सएमएल का उपयोग करने वाली प्रक्रिया को टाइमस्टैम्प द्वारा इसे टाइप किया जाता है ..

मुझे लगता है कि नोड को टेक्स्ट के रूप में जोड़ना एक कच्चा तरीका है .. हालांकि मुझे लगता है अंत टैग के बाद नोड जोड़ देगा ??

किसी भी विचार को कृतज्ञता से प्राप्त .. डेविड।

उत्तर

2

यहां पहले से ही कई सभ्य उत्तर हैं, हालांकि इस पर एक और स्पिन डालने के लिए, क्या आप वाकई इस डेटा को एक्सएमएल फ़ाइल के रूप में संग्रहीत करने की ज़रूरत है?

आपके द्वारा संग्रहीत डेटा काफी सरल दिखता है (यानी तीन फ़ील्ड्स, दिनांक, प्रकार और कुछ स्ट्रिंग डेटा वाला रिकॉर्ड। यदि आपको XML द्वारा प्रदान किए गए अतिरिक्त लाभों की आवश्यकता नहीं है (see here) तो क्यों न केवल मूल का उपयोग करें सीएसवी? इस तरह आप बस सिर्फ File.AppendText("filename") के माध्यम से एक लॉग फ़ाइल की तरह यह करने के लिए जोड़कर रख सकते हैं।

(नरक, तो यह और भी प्रवेश प्रबंधन करने के लिए log4net की तरह कुछ का उपयोग करना संभव हो सकता है और किसी भी गृह व्यवस्था को साफ।)

+0

हां, यह समस्या को दूर करने का एक समझदार तरीका हो सकता है। –

+0

धन्यवाद, वास्तव में सभी के लिए, निश्चित रूप से कुछ अच्छी अंतर्दृष्टि। XML का उपयोग करने के एकमात्र कारणों में से एक (कि, और तथ्य यह है कि यह पहले से ही किसी मौजूदा सिस्टम में कुछ नलसाजी है) कुछ मौजूदा कोड के साथ उपयोग करने के लिए XML डेटा को डेटासेट/तालिका में लोड करने में सक्षम होना है .. लेकिन टिप्पणियां दी गईं इस प्रश्न से, और बाद में डेटा लोड करने के लिए मेरे पास विलंबता है, सीएसवी विकल्प शायद रास्ता है .. (हालांकि हेनक का stream.position विकल्प भी बहुत बुरा नहीं है!) फिर से धन्यवाद !! –

4

किसी भी तरह, आपको XML फ़ाइल को पढ़ना होगा, क्योंकि आप दस्तावेज़ में नोड नहीं जोड़ सकते हैं।

एक XML फ़ाइल जड़ क्लोज़िंग के ठीक पहले केवल एक ही जड़ हो सकता है, इसलिए नए नोड पिछले डेटा तत्व के बाद जोड़ा जा करना होगा, लेकिन,। अन्यथा एक्सएमएल मान्य नहीं है।

+0

हाँ सच .. मुझे एहसास है कि शायद यह मामला होने जा रहा है .. लेकिन सोचा कि सवाल क्यों नहीं पूछें! शायद ज़रुरत पड़े! –

-3

सिर्फ

string s = File.ReadAllText(path) 
s = s.replace("</root>", newnode + "</root>") 
File.WriteAllText(s, path) 
+0

जो अभी भी इसे लोड करता है ... यह सिर्फ एक्सएमएल पार्सिंग को छोड़ देता है, एक मामूली बचत। आई/ओ महंगा है। –

+0

कूल .. नया नोड जोड़ने का अच्छा आसान तरीका .. मुझे लगता है कि इसका मतलब अभी भी xml फ़ाइल को पढ़ना है, लेकिन फिर मैंने अनुमान लगाया कि यह मामला होगा, इसलिए इसके लिए धन्यवाद, अच्छा साफ उदाहरण! –

+0

-1। प्रश्न बड़ी फाइलें खोलने के बारे में है। मुझे यकीन नहीं है कि स्मृति में एक बड़ी फ़ाइल लोड करना सबसे अच्छा तरीका है, जब उसके लिए धाराएं होती हैं। –

8

का उपयोग किसी भी XML API या उपकरण के साथ।

आप फ़ाइल को टेक्स्ट के रूप में खोल सकते हैं, </root> की स्थिति ढूंढ सकते हैं और वहां से ओवरराइटिंग शुरू कर सकते हैं। और निश्चित रूप से </root> फिर से जोड़ें।


एक त्वरित और गंदे दृष्टिकोण, यह बहुत मजबूत नहीं है:

  • सुनिश्चित करें कि आप प्रारंभिक फ़ाइल तैयार करते हैं, वहाँ कुछ भी नहीं (कोई खाली स्थान के) बंद टैग के बाद होना चाहिए
  • आप ASCII या UTF8 एन्कोडिंग

====

उपयोग सुनिश्चित करें
string closeTag = "</root>"; 
int closeLength = Encoding.UTF8.GetBytes(closeTag).Length; 

var fs = System.IO.File.Open(filename, System.IO.FileMode.Open); 
fs.Position = fs.Length - closeLength; 

var writer = new StreamWriter(fs); // after the Position is set 

writer.WriteLine(newTag); 
writer.Write(closeTag); // NOT WriteLine !! 

writer.Close(); 
fs.Close(); 

और निश्चित रूप से आप using() {} ब्लॉक का उपयोग करने के बारे में जानते हैं।

+0

हां सच .. वास्तव में अमाशको ने बस इसके बारे में टिप्पणी की .. तो धन्यवाद! –

+0

@ डेविड: नहीं, मेरा मतलब था _not_ इसे सब कुछ पढ़ना लेकिन Stream.Position का उपयोग करना। –

+0

आप इसे एक एक्सएमएल एपीआई (एक्सएमएल रीडर/एक्सएमएलवाइटर) के साथ कर सकते हैं। इसे कार्यान्वित करना आसान नहीं है (एक्सएमएल फाइल की संभावित सामग्री के आधार पर), लेकिन करने योग्य। यदि आपके पास मूलभूत टैग और उपरोक्त गुण हैं, तो यह भी मुश्किल नहीं होगा। – TToni

1

निर्भर करता है।

यदि आप इसे "सही" तरीका करना चाहते हैं, तो आपको फ़ाइल और एक्सएमएल को पढ़ना होगा। उदाहरण के लिए आप XmlReader क्लास का उपयोग कर इसे पूरी तरह स्मृति में लोड करने से बच सकते हैं।

हालांकि, यदि आप निश्चित रूप से टेक्स्ट लेआउट और फ़ाइल के एन्कोडिंग को पूरी तरह से जानते हैं, तो आप इसे यादृच्छिक-पहुंच फ़ाइल (फ़ाइलस्ट्रीम) के रूप में खोलकर इसे पूरी तरह से पढ़ने और पुनः लिखने से बच सकते हैं, अंत तक छोड़ सकते हैं (शून्य "< रूट />"), वहां नई प्रविष्टि जोड़ें और फिर "< रूट />" लिखें।

1

मैं पूरी फ़ाइल को पढ़ने के बिना आप क्या कर रहे हैं करने के लिए एक तरह से नहीं देख सकते हैं, लेकिन एक समाधान के रूप हो सकता है आप यानी रूट नोड के बिना एक सादा पाठ के रूप में फ़ाइल का इलाज कर सकता है (यह अमान्य XML हो जाएगा)। फिर, आप फ़ाइल में नए नोड्स को सादा पाठ के रूप में जोड़ सकते हैं।और, चूंकि आपकी एक्सएमएल पार्सिंग प्रक्रिया पूरी फाइल को वैसे भी लोड करती है, इसलिए यह एक्सएमएल के रूप में इलाज करने से पहले रूट नोड जोड़ सकती है।

1
System.IO.FileInfo[] aryFi = di.GetFiles("*.xml"); 


foreach (System.IO.FileInfo fi in aryFi) { 

System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument(); 
xmlDocument.Load(fi.FullName); 

XmlNode refelem = xmlDocument.LastChild; 
XmlNode newElem = xmlDocument.CreateNode("element", "something", ""); 
newElem.InnerText = "sometext"; 
xmlDocument.InsertAfter(newElem, refelem); 
} 

मेरा मानना ​​है कि एक नोड खोलना और डालना सबसे अच्छा विकल्प होगा। किसी भी तरह से आप एलडी को आईओ का उपयोग करने की ज़रूरत है, यह उचित तरीके क्यों नहीं है?

एकल फाइल के लिए

System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument(); 
xmlDocument.Load("file path"); 

XmlNode refelem = xmlDocument.LastChild; 
XmlNode newElem = xmlDocument.CreateNode("element", "something", ""); 
newElem.InnerText = "sometext"; 
xmlDocument.InsertAfter(newElem, refelem); 
+0

कि '* .xml' कहीं से नहीं आता है। और यह अभी भी पूरी फ़ाइल (और कुछ और) लोड करता है, सवाल यह टालने के बारे में है। –

+0

हां यह था कि यदि आप निर्देशिका में सभी एक्सएमएल फाइलों पर एक ही कार्रवाई करना चाहते हैं। इससे पहले कोड है जो निर्देशिका जानकारी प्राप्त करता है। आपके मामले में आप सभी फाइलों के माध्यम से लूपिंग नहीं करेंगे। मैं एकल फ़ाइल के लिए कोड जोड़ने जा रहा हूँ। – Ismail

+0

यदि मैं इस स्थिति में था और चूंकि दोनों दृष्टिकोणों के लिए आपको आईओ कॉल करने की आवश्यकता होती है तो मेरे लिए पसंदीदा टेक्स्ट के बजाय एक्सएमएल नोड जोड़ना होगा, आपके पास इस तरह से ऐसा करने की योजना बनाने के कुछ कारण हो सकते हैं। – Ismail

1

हैं एक्सएमएल लोड नहीं करके, आप एक डोम पेड़ का निर्माण नहीं मतलब, VTD-एक्सएमएल केवल API कि आप पेस्ट विभाजन कट या संवर्द्धित संशोधित करने के लिए अनुमति देता है। इसके अलावा, क्योंकि VTD-XML स्मृति प्रभावशाली है, आपको XML दस्तावेज़ के आकार के बारे में चिंता करने की आवश्यकता नहीं होगी। जावा में एक समान पोस्ट How to update large XML file पर है। ध्यान दें कि vtd-xml जावा, सी #, सी और सी ++ में उपलब्ध है।

+0

ठीक है, मुझे लगता है कि आपका उपयोगकर्ता नाम प्रकटीकरण के रूप में गिना जाता है। –

+0

इस बारे में नहीं सुना था .. असल में शायद इस समाधान के लिए अधिकतर हो सकता है, लेकिन निश्चित रूप से इसे देखेगा .. –

+0

@ हेंक: मैं असहमत हूं, और स्पैम-फ्लैगिंग कर रहा हूं (एक उत्तर को छोड़कर मैंने जवाब दिया)। –

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

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