2009-10-01 11 views
6

मैं एक विधि को ओवरराइड कर रहा हूं जिसमें XmlReader पारित किया जा रहा है, मुझे एक विशिष्ट तत्व ढूंढना होगा, एक विशेषता जोड़ें और फिर या तो एक नया XmlReader बनाएं या बस प्रतिस्थापित करें संशोधित सामग्री के साथ मौजूदा एक। मैं सी # 4.0XmlReader - मुझे एक तत्व को संपादित करने और एक नया उत्पाद बनाने की आवश्यकता है

का उपयोग कर रहा हूं मैंने XElement (Linq) का उपयोग करके जांच की है लेकिन मैं मौजूदा तत्व में हेरफेर नहीं कर सकता और एक विशेषता और मूल्य जोड़ सकता हूं।

मुझे पता है कि XmlWriter जो शानदार होगा WriteAttributeString है, लेकिन फिर मुझे यकीन है कि यह सब कैसे हो गया

मैं की तरह कुछ करने में सक्षम होना चाहते हैं नहीं कर रहा हूँ --- यह छद्म कोड है!

public XmlReader DoSomethingWonderful(XmlReader reader) 
{ 
    Element element = reader.GetElement("Test"); 
    element.SetAttribute("TestAttribute","This is a test"); 
    reader.UpdateElement(element); 
    return reader; 
} 

उत्तर

11

XmlReader/लेखक अनुक्रमिक अभिगम धाराएं हैं। आपको एक छोर पर पढ़ना होगा, स्ट्रीम को स्ट्रीम करना होगा, और इसे दूसरे सिरे से लिखना होगा। लाभ यह है कि आपको पूरी चीज को स्मृति में पढ़ने और डीओएम बनाने की आवश्यकता नहीं है, जो कि आप किसी भी XmlDocument- आधारित दृष्टिकोण के साथ प्राप्त करेंगे।

इस विधि मिलना चाहिए आप आरंभ:

private static void PostProcess(Stream inStream, Stream outStream) 
{ 
    var settings = new XmlWriterSettings() { Indent = true, IndentChars = " " }; 

    using (var reader = XmlReader.Create(inStream)) 
    using (var writer = XmlWriter.Create(outStream, settings)) { 
     while (reader.Read()) { 
      switch (reader.NodeType) { 
       case XmlNodeType.Element: 
        writer.WriteStartElement(reader.Prefix, reader.Name, reader.NamespaceURI); 
        writer.WriteAttributes(reader, true); 

        // 
        // check if this is the node you want, inject attributes here. 
        // 

        if (reader.IsEmptyElement) { 
         writer.WriteEndElement(); 
        } 
        break; 

       case XmlNodeType.Text: 
        writer.WriteString(reader.Value); 
        break; 

       case XmlNodeType.EndElement: 
        writer.WriteFullEndElement(); 
        break; 

       case XmlNodeType.XmlDeclaration: 
       case XmlNodeType.ProcessingInstruction: 
        writer.WriteProcessingInstruction(reader.Name, reader.Value); 
        break; 

       case XmlNodeType.SignificantWhitespace: 
        writer.WriteWhitespace(reader.Value); 
        break; 
      } 
     } 
    } 
} 

यह काफी के रूप में अपने स्वयं के XmlWriter पाने के रूप में साफ नहीं है, लेकिन मुझे लगता है कि यह बहुत आसान है।

[संपादित करें]

कैसे आप एक बार में दो धाराओं खोलता था कुछ इस तरह हो सकता है का एक उदाहरण:

using (FileStream readStream = new FileStream(@"c:\myFile.xml", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write)) { 
    using (FileStream writeStream = new FileStream(@"c:\myFile.xml", FileMode.OpenOrCreate, FileAccess.Write)) { 
    PostProcess(readStream, writeStream); 
    } 
} 
1

आप आसानी से XmlReader साथ ऐसा नहीं कर सकते - कम से कम, नहीं पाठक से में पूरे XML दस्तावेज़ पढ़ने, यह साथ futzing और फिर एक नई XmlReader परिणाम से बनाए बिना। यह XmlReader का उपयोग करने के बहुत से बिंदु को हरा देता है - अर्थात बड़े दस्तावेज़ों को स्ट्रीम करने की क्षमता।

आप कर सकते थे संभावित, XmlReader से निकाले जाते हैं अग्रेषण सबसे विधि मौजूदा पाठक के लिए कहता है, लेकिन उनमें बाधा उत्पन्न कर रहा जहां उचित अतिरिक्त विशेषताएं जोड़ने का तरीका आदि ... लेकिन मुझे लगता है कि कोड वास्तव में काफी जटिल और नाजुक हो जाएगा।

+0

उत्तर के लिए धन्यवाद, मैंने सोचा (उम्मीद है) यह एक अच्छा सरल ऑपरेशन होगा। मैं एकमात्र ऐसा व्यक्ति नहीं हो सकता जो कभी भी एक निश्चित तत्व तक एक्सएमएल में पढ़ना चाहता था, इसे संपादित करें और फिर बदले गए परिणाम को आउटपुट करें। - अगर आप आज पढ़ने में सामान्य से अधिक शपथ लेते हैं .... यह मैं हूँ !! –

+0

@Phill: ऐसा करना आसान है, स्ट्रीमिंग तरीके से नहीं, मुझे डर है :( –

+0

'एक्सएमएल रीडर' उप-वर्ग (वास्तव में आप 'एक्सएमएलटीक्स्ट रीडर' उपclass करेंगे, जब तक कि आप अमूर्त तरीकों को लागू करने की तरह महसूस नहीं करते) एक है दिलचस्प चुनौती। –

1

मैं निम्नलिखित डक्ट टेप कोडिंग

public XmlReader FixUpReader(XmlReader reader) 
    { 
     reader.MoveToContent(); 

     string xml = reader.ReadOuterXml(); 

     string dslVersion = GetDSLVersion(); 
     string Id = GetID(); 

     string processedValue = string.Format("<ExampleElement dslVersion=\"{1}\" Id=\"{2}\" ", dslVersion, Id); 
     xml = xml.Replace("<ExampleElement ", processedValue); 
     MemoryStream ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(xml)); 
     XmlReaderSettings settings = new XmlReaderSettings(); 

     XmlReader myReader = XmlReader.Create(ms); 
     myReader.MoveToContent(); 
     return myReader; 
    } 

मैं इसे इस तरह से करने के लिए गंदा लग रहा है, लेकिन यह काम कर रहा है का उपयोग कर इसे तय ....

+1

मुझे यह सुनिश्चित नहीं होगा कि यह काम कर रहा है। पाठक जो आप वापस कर रहे हैं वह नहीं जा रहा है इस के बाद तत्व में स्थानांतरित करने में सक्षम हो, क्योंकि वह तत्व (वास्तव में, शेष पाठक जो शेष पाठक प्रसंस्करण कर रहा था) सभी बैकिंग स्ट्रीम में नहीं है। –

0

मैं नहीं बल्कि XmlDocument में xml लोड करने के लिए पसंद करेंगे ऑब्जेक्ट का उपयोग करें और मान को संशोधित करने के लिए Attributes संग्रह का उपयोग करें और इस मान को अपडेट करने के लिए Save विधि पर कॉल करें। मेरे नीचे कोड काम करता है।

public static void WriteElementValue (string sName, string element, string value) 
{ 
    try 
    { 
    var node = String.Format("//elements/element[@name='{0}']", sName); 
    var doc = new XmlDocument { PreserveWhitespace = true }; 
    doc.Load(configurationFileName); 

    var nodeObject = doc.SelectSingleNode(node); 

    if (nodeObject == null) 
     throw new XmlException(String.Format("{0} path does not found any matching 
     node", node)); 

    var elementObject = nodeObject[element]; 

    if (elementObject != null) 
    { 
     elementObject.Attributes["value"].Value = value; 
    } 

    doc.Save(configurationFileName); 
} 
catch (Exception ex) 
{ 
    throw new ExitLevelException(ex, false); 
} 

}

मैं भी जब आप का उपयोग XmlWriter या XmlSerializer व्हाइटस्पेस सही ढंग से संरक्षित नहीं किया गया देखा होगा, यह कष्टप्रद हो सकता है कभी कभी

-2
 string newvalue = "10"; 
     string presentvalue = ""; 
     string newstr = ""; 
     XmlReader xmlr = XmlReader.Create(new StringReader(str)); 

     while (xmlr.Read()) 
     { 
      if (xmlr.NodeType == XmlNodeType.Element) 
      { 
       if (xmlr.Name == "priority") 
       { 
        presentvalue = xmlr.ReadElementContentAsString(); 
        newstr = str.Replace(presentvalue, newvalue); 
       } 
      } 

     } 

// newstr फाइल करने के लिए वापस लिखा जा सकता है। ..वह संपादित xml

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

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