2011-07-07 10 views
6

के साथ एक्सएमएल से डुप्लिकेट विशेषताओं को कैसे हटाएं मैं किसी तृतीय पक्ष प्रदाता से कुछ एक्सएमएल फाइलों को पार्स कर रहा हूं और दुर्भाग्यवश यह हमेशा अच्छी तरह से गठित एक्सएमएल नहीं है क्योंकि कभी-कभी कुछ तत्वों में डुप्लिकेट गुण होते हैं।सी #

मेरे पास स्रोत पर नियंत्रण नहीं है और मुझे नहीं पता कि कौन से तत्वों में डुप्लिकेट विशेषता हो सकती है और न ही मैं पहले से ही डुप्लिकेट विशेषता नामों को जानता हूं।

जाहिर है, एक XMLDocument वस्तु में सामग्री लोड डुप्लिकेट पर एक XmlException तो मैं हालांकि मैं एक XmlReader इस्तेमाल कर सकते हैं तत्व द्वारा हालांकि XML तत्व कदम और सौदा डुप्लिकेट के साथ जिम्मेदार बताते हैं, जब मैं अपमानजनक तत्व को पाने के लिए विशेषताओं को जन्म देती है।

हालांकि, XmlExceptionreader.Read() पर उठाया गया है - इससे पहले कि मुझे तत्व के गुणों की खोज करने का मौका मिले।

public static void ParseTest() 
{ 
    const string xmlString = 
     @"<?xml version='1.0'?> 
     <!-- This is a sample XML document --> 
     <Items dupattr=""10"" id=""20"" dupattr=""33""> 
      <Item>test with a child element <more/> stuff</Item> 
     </Items>"; 

    var output = new StringBuilder(); 
    using (XmlReader reader = XmlReader.Create(new StringReader(xmlString))) 
    { 
     XmlWriterSettings ws = new XmlWriterSettings(); 
     ws.Indent = true; 
     using (XmlWriter writer = XmlWriter.Create(output, ws)) 
     { 
      while (reader.Read()) /* Exception throw here when Items element encountered */ 
      { 
       switch (reader.NodeType) 
       { 
        case XmlNodeType.Element: 
         writer.WriteStartElement(reader.Name); 
         if (reader.HasAttributes){ /* CopyNonDuplicateAttributes(); */} 
         break; 
        case XmlNodeType.Text: 
         writer.WriteString(reader.Value); 
         break; 
        case XmlNodeType.XmlDeclaration: 
        case XmlNodeType.ProcessingInstruction: 
         writer.WriteProcessingInstruction(reader.Name, reader.Value); 
         break; 
        case XmlNodeType.Comment: 
         writer.WriteComment(reader.Value); 
         break; 
        case XmlNodeType.EndElement: 
         writer.WriteFullEndElement(); 
         break; 
       } 
      } 

     } 
    } 
    string str = output.ToString(); 
} 

वहाँ एक और तरीका है इनपुट को पार्स और नियमित अभिव्यक्ति और स्ट्रिंग परिवर्तन का उपयोग किए बिना डुप्लिकेट विशेषताओं को दूर करने के है:

यहाँ मुद्दा प्रदर्शित करने के लिए एक नमूना विधि है?

+0

यह केवल तभी संभव हो सकता है जब एक्सएमएल प्रोसेसर एपीआई प्रदाता किसी भी हुक जो आपको प्रसंस्करण में हुक करने और त्रुटि शर्तों को संभालने की अनुमति देता है – Ankur

+0

दिलचस्प समस्या, समाधान देखने के लिए तत्पर हैं! –

+2

एक्सएमएल का उपयोग कर इस समस्या का कोई समाधान नहीं होगा, क्योंकि आपका इनपुट एक्सएमएल नहीं है। आप कहते हैं कि आपके पास इनपुट पर कोई नियंत्रण नहीं है, लेकिन क्या आप कम से कम अपने वरिष्ठों को यह जान सकते हैं कि आपका विक्रेता आपको एक्सएमएल नहीं भेज रहा है? क्या आप कम से कम यह सुनिश्चित कर सकते हैं कि आपका _vendor_ यह जानता है?इस डेटा को भेजने के लिए पर्याप्त कोई भी मूर्ख बेवकूफ हो सकता है यह महसूस करने के लिए पर्याप्त नहीं है कि यह एक्सएमएल नहीं है। –

उत्तर

3

मुझे XML दस्तावेज़ के रूप में XML के बारे में सोचकर समाधान मिला। फिर ओपन-सोर्स Html Agility Pack लाइब्रेरी का उपयोग करके, मैं वैध एक्सएमएल प्राप्त करने में सक्षम था।

चाल xml को पहले HTML शीर्षलेख से सहेजना था।
तो इस तरह एक HTML घोषणा के साथ XML घोषणा
<?xml version="1.0" encoding="utf-8" ?>
बदल देते हैं:
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

एक बार सामग्री दायर करने के लिए सहेजे जाते हैं, इस विधि एक मान्य XML दस्तावेज़ वापस आ जाएगी।

// Requires reference to HtmlAgilityPack 
public XmlDocument LoadHtmlAsXml(string url) 
{ 
    var web = new HtmlWeb(); 

    var m = new MemoryStream(); 
    var xtw = new XmlTextWriter(m, null); 

    // Load the content into the writer 
    web.LoadHtmlAsXml(url, xtw); 

    // Rewind the memory stream 
    m.Position = 0; 

    // Create, fill, and return the xml document 
    XmlDocument xmlDoc = new XmlDocument(); 
    xmlDoc.LoadXml((new StreamReader(m)).ReadToEnd()); 
    return xmlDoc; 
} 

डुप्लिकेट विशेषता नोड्स स्वचालित रूप से बाद में विशेषता मान पहले वाले को अधिलेखित करने के साथ हटा दिया है।

0

ठीक लगता है कि आप त्रुटि को पकड़ने के लिए की जरूरत है: निम्नलिखित गुण प्राप्त करने के

reader.MoveToFirstAttribute(); 

और

reader.MoveToNextAttribute() 

:

तो फिर तुम निम्न विधियों का उपयोग करने के लिए सक्षम होना चाहिए

reader.Value 
reader.Name 

यह आपको सभी विशेषता मान प्राप्त करने में सक्षम करेगा।

+0

मैं त्रुटि को पकड़ सकता हूं और वर्तमान नोड पर गुणों को संसाधित कर सकता हूं (यानी गैर डुप्लीकेट कॉपी करता हूं) लेकिन समस्या तब बाकी दस्तावेज़ को प्रोसेसिंग के साथ जारी रखती है क्योंकि 'reader.Read()' झूठी रिटर्न होती है, इसलिए कोई और तत्व संसाधित नहीं होता है। – Catch22

+0

# कैच 22, हाँ, कोड को फिर से शुरू करने की कोशिश करते समय मैं उस पर आया था। मुझे उम्मीद थी कि आपको इसके चारों ओर एक रास्ता मिल जाएगा। यहां एक नज़र डालें: http://bytes.com/topic/c-sharp/answers/827965-how-handle-xml-parsing-exception ऐसा लगता है कि XMLReader किसी कारण से असहिष्णु त्रुटि है। यह आमतौर पर अच्छी खबर होगी लेकिन आपके मामले में इसका मतलब है कि मेरा सुझाया गया समाधान शायद काम नहीं करेगा। माफ़ कीजिये – openshac