2009-09-29 20 views
12

हमारे पास एक स्ट्रिंग फ़ील्ड है जिसमें XML या सादा पाठ हो सकता है। एक्सएमएल में <?xml हेडर नहीं है, और कोई मूल तत्व नहीं है, यानी अच्छी तरह से गठित नहीं है।कैसे बताएं कि स्ट्रिंग xml है या नहीं?

हमें एक्सएमएल डेटा को रेडक्ट करने, एलिमेंटिंग तत्व और एट्रिब्यूट वैल्यू को खाली करने में सक्षम होना चाहिए, केवल उनके नाम छोड़कर, इसलिए मुझे यह जांचने की आवश्यकता है कि यह स्ट्रिंग फिर से एक्सएमएल है या नहीं।

string redact(string eventDetail) 
{ 
    string detail = eventDetail.Trim(); 
    if (!detail.StartsWith("<") && !detail.EndsWith(">")) return eventDetail; 
    ... 

वहाँ एक बेहतर तरीका है:

वर्तमान में मैं इस दृष्टिकोण का उपयोग कर रहा हूँ?

क्या इस दृष्टिकोण से कोई बढ़िया मामला याद आ सकता है?

मुझे सराहना है कि मैं XmlDocument.LoadXml का उपयोग कर सकता हूं और XmlException पकड़ सकता हूं, लेकिन यह एक महंगा विकल्प जैसा लगता है, क्योंकि मुझे पहले से ही पता है कि बहुत सारे डेटा एक्सएमएल में नहीं होंगे।

यहाँ XML डेटा का एक उदाहरण है, के अलावा एक मूल तत्व (जो, स्थान बचाने के लिए के बाद से वहाँ डेटा का एक बहुत हो जाएगा छोड़ दिया जाता है) याद आ रही से, हम यह मान सकते हैं कि यह अच्छी तरह से बनाई है:

<TableName FirstField="Foo" SecondField="Bar" /> 
<TableName FirstField="Foo" SecondField="Bar" /> 
... 

वर्तमान में हम केवल विशेषता आधारित मानों का उपयोग कर रहे हैं, लेकिन यदि डेटा अधिक जटिल हो जाता है तो हम भविष्य में तत्वों का उपयोग कर सकते हैं।

समाधान

अनेक टिप्पणियाँ के आधार पर (धन्यवाद लोग!)

string redact(string eventDetail) 
{ 
    if (string.IsNullOrEmpty(eventDetail)) return eventDetail; //+1 for unit tests :) 
    string detail = eventDetail.Trim(); 
    if (!detail.StartsWith("<") && !detail.EndsWith(">")) return eventDetail; 
    XmlDocument xml = new XmlDocument(); 
    try 
    { 
     xml.LoadXml(string.Format("<Root>{0}</Root>", detail)); 
    } 
    catch (XmlException e) 
    { 
     log.WarnFormat("Data NOT redacted. Caught {0} loading eventDetail {1}", e.Message, eventDetail); 
     return eventDetail; 
    } 
    ... // redact 
+0

मैं लोडएक्सएमएल के साथ जाऊंगा, इस तरह आप इनपुट किए गए "एक्सएमएल" डेटा को मान्य मानते हैं। यदि आप अपनी विधि (कोड) का उपयोग करते हैं, तो आप XML को खराब कर सकते हैं जो परीक्षण पास करेगा। – Martin

+0

देखें http://stackoverflow.com/questions/1072158/validate-xml-syntax-only-in-c – Graviton

+0

क्या आप इसे स्वयं लिख रहे हैं? मुझे समझ में नहीं आता है कि आप इसे इस तरह लिख रहे हैं कि आप सही तरीके से क्षेत्रों की व्याख्या नहीं कर सकते हैं, फिर ...? –

उत्तर

3

एक समाधान दोनों समाधानों को मिश्रण करना है। आप अपनी रेडैक्ट विधि का उपयोग कर सकते हैं और इसे लोड करने का प्रयास कर सकते हैं (अगर अंदर)। इस तरह, आप केवल एक अच्छी तरह से गठित xml होने की संभावना है, और अधिकांश गैर-एक्सएमएल प्रविष्टियों को त्यागने की कोशिश करेंगे।

+0

अच्छा विचार, धन्यवाद। – si618

+0

मैंने इसे सबसे उपयुक्त उत्तर के रूप में चिह्नित किया है, क्योंकि मुझे लगता है कि यह मेरी समस्या को सबसे कुशल तरीके से हल करता है अधिकांश मामलों के लिए, स्टार्टविथ <और एंड्स विथ> गैर-एक्सएमएल डेटा फ़िल्टर करेगा, और दुर्लभ स्थितियों जैसे ईरा बैक्सटर का वर्णन है, XmlException को पकड़ने से उन्हें हल किया जाएगा। – si618

8

आप अच्छी तरह से पहली जगह में एक्सएमएल का गठन नहीं स्वीकार करने के लिए जा रहे हैं, मैं अपवाद को पकड़ने लगता है इसे संभालने का सबसे अच्छा तरीका।

+0

मैंने आपको 2 सेकंड तक हराया, हा! – Martin

+0

हा, हा! तुम जीते! – lod3n

+0

आप पोस्ट को संपादित भी कर सकते हैं और "फर्स्ट!" डाल सकते हैं – Spence

2

यदि आपका लक्ष्य विश्वसनीयता है तो सबसे अच्छा विकल्प यह निर्धारित करने के लिए XmlDocument.LoadXml का उपयोग करना है कि यह मान्य XML है या नहीं। डेटा का एक पूर्ण पार्स महंगा हो सकता है लेकिन यह विश्वसनीय तरीका है कि यह वैध XML है या नहीं, यह एकमात्र तरीका है। अन्यथा कोई भी चरित्र जिसे आप बफर में जांच नहीं करते हैं, डेटा को अवैध XML हो सकता है।

+0

मुझे नहीं लगता कि 'XmlDocument' यहां एक अच्छी पसंद है - उसे केवल सत्यापित करने के लिए डोम की आवश्यकता नहीं है। ऐसा लगता है कि 'एक्सएमएल रीडर' और 'कोशिश करें {जबकि (पाठक। पढ़ें();} पकड़ें (एक्सएमएलएक्सप्शन पूर्व) {...}' अधिक हल्का दृष्टिकोण होगा। –

+0

@ पावेल, लेकिन मुझे एक्सएमएल को फिर से संशोधित करने के लिए संशोधित करना होगा डेटा, इसलिए XmlDocument की आवश्यकता। – si618

+0

सहमत है, लेकिन अगर मैं दृष्टिकोण (सैमुअल के विचार के अनुसार) जोड़ता हूं, तो मुझे 99% सादा पाठ को स्टार्ट्सविथ और एंड्स के साथ कोड के साथ पकड़ना चाहिए, और दूसरे 1% को पकड़ा जाना चाहिए यदि लोडएक्सएमएल एक्सएमएलएक्सप्शन फेंकता है। – si618

0

एक्सएमएल रूट तत्व नहीं हैं (यानी यह एक XML टुकड़ा, नहीं एक पूर्ण दस्तावेज है), उसके बाद निम्न पूरी तरह से वैध नमूना है, साथ ही हो सकता है - लेकिन अपने डिटेक्टर से मेल नहीं होगा:

foo<bar/>baz 

वास्तव में, कोई भी टेक्स्ट स्ट्रिंग मान्य XML खंड होगा (मान लें कि मूल XML दस्तावेज़ केवल कुछ तत्व लपेटने वाला मूल तत्व था, और आप रूट तत्व टैग को दूर लेते हैं)!

1

इस बात पर निर्भर करता है कि आप कितना सटीक परीक्षण चाहते हैं। यह मानते हुए कि आपके पास पहले से ही आधिकारिक < xml नहीं है, आप पहले से ही ऐसा कुछ पता लगाने की कोशिश कर रहे हैं जो एक्सएमएल नहीं है। आदर्श रूप से आप एक पूर्ण एक्सएमएल पार्सर द्वारा पाठ को पार्स करेंगे (जैसा कि आप लोडएक्सएमएल का सुझाव देते हैं); जो भी इसे अस्वीकार करता है वह एक्सएमएल नहीं है। सवाल यह है कि, क्या आप परवाह करते हैं यदि आप गैर-एक्सएमएल स्ट्रिंग स्वीकार करते हैं? उदाहरण के लिए, आप XML के रूप में

<the quick brown fox jumped over the lazy dog's back> 

को स्वीकार करने और इसे अलग करना साथ ठीक कर रहे हैं? यदि हां, तो आपकी तकनीक ठीक है। यदि नहीं, तो आपको यह तय करना होगा कि आप कितना परीक्षण चाहते हैं और उस डिग्री के साथ पहचानकर्ता को कोड करें।

+0

हां, यह ऐसी चीज है जो मुझे मारने से डरती है। – si618

1

डेटा आपके पास कैसे आ रहा है? इसके आसपास के अन्य प्रकार के डेटा क्या हैं? शायद एक बेहतर तरीका है; शायद आप जिस डेटा को नियंत्रित करते हैं उसे टोकनिस कर सकते हैं, और उसके बाद यह अनुमान लगाएं कि उन टोकन के भीतर जो कुछ भी नहीं है, वह एक्सएमएल है, लेकिन हमें और जानना होगा।

इस तरह एक प्यारा समाधान विफल होने पर, मुझे लगता है कि आपके पास क्या है ठीक है (यह सत्यापित करने के लिए कि यह उन पात्रों के साथ शुरू होता है और समाप्त होता है)।

हमें वास्तव में डेटा प्रारूप के बारे में अधिक जानने की आवश्यकता है।

0
try 
{ 
    XmlDocument myDoc = new XmlDocument(); 
    myDoc.LoadXml(myString); 
} 
catch(XmlException ex) 
{ 
    //take care of the exception 
} 
+1

बेशक, और यह सवाल में कहा गया है। लेकिन अपवादों को पकड़ना महंगा है जब मुझे पता है कि बहुत सारे डेटा एक्सएमएल नहीं हैं। – si618

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