2010-08-10 27 views
10

के विरुद्ध एक्सएमएल को प्रमाणित करने के लिए .NET का उपयोग करना मैं परीक्षण (सत्य या गलत) परीक्षण करना चाहता हूं कि क्या एक मनमानी एक्सएमएल फ़ाइल किसी दिए गए स्कीमा से मेल खाती है।एक स्कीमा

क्या इसके लायक है के लिए, स्कीमा Word 2003 WordML स्कीमा, जो माइक्रोसॉफ्ट के बारे में 7 *.xsd फ़ाइलों की एक सूची का उपयोग कर परिभाषित करता है।

इन फ़ाइलों में से एक भी W3C xml.xsd फ़ाइल भी शामिल है, निम्न कथन को शामिल करके:

<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace" 
    schemaLocation="http://www.w3.org/2001/xml.xsd"></xsd:import> 

मैं की तरह नेट कोड का उपयोग कर रहा मान्यकरण करना निम्नलिखित:

public static void validate(string filename) 
    { 
     XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.Schemas.Add(
      "http://schemas.microsoft.com/office/word/2003/wordml", 
      //to get this file I downloaded "Office 2003: XML Reference Schemas", i.e. "Office2003XMLSchema.exe" 
      @"C:\Program Files\Microsoft Office 2003 Developer Resources\Microsoft Office 2003 XML Reference Schemas\WordprocessingML Schemas\wordnet.xsd" 
      ); 
     settings.ValidationType = ValidationType.Schema; 
     settings.ValidationEventHandler += new ValidationEventHandler(validationEventHandler); 
     XmlReader xmlReader = XmlReader.Create(filename, settings); 
     while (xmlReader.Read()) { } 
    } 

मेरे समस्या यह है कि यदि मैं इस कोड को एक मशीन पर चलाता हूं जो इंटरनेट से कनेक्ट नहीं है, तो मुझे XmlSchemaValidationException त्रुटि मिलती है जिससे यह xml.xsd नहीं मिल सकता है।

इसे ठीक करने के लिए, मैंने xml.xsd की एक प्रति डाउनलोड की है, और इसे settings.Schemas.Add विधि का उपयोग करके स्पष्ट रूप से जोड़ना है: जब मशीन इंटरनेट से कनेक्ट नहीं होती है तो प्रमाणीकरण अब सही तरीके से काम करता है।

लेकिन जब मशीन इंटरनेट से जुड़ा है, मैं अब कि The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared. कह कोई त्रुटि मिलती है।

तो जाहिर है कि मुझे या तो इसे स्पष्ट रूप से जोड़ने की ज़रूरत है, या मैं इस बात पर निर्भर करता हूं कि मशीन इसे चुपचाप इंटरनेट से डाउनलोड करने में सक्षम है या फिर शायद इसे डाउनलोड करने में सक्षम है, और इसे कैश किया गया है कहीं)।

तो, यह "अगर मैं करता हूं और शापित हूं तो मैं शापित हूं"। क्या मुझे इसे एक तरह से करने की कोशिश है, अपवाद पकड़ें और फिर इसे दूसरी तरफ आज़माएं? या क्या एक और सुरुचिपूर्ण समाधान है?

उत्तर

4

हम आपका कोड नहीं देख सकते हैं, लेकिन कई कार्यान्वयन में यह एक कैटलॉग रिज़ॉल्वर का उपयोग कर .xsd के स्थानीय अनुरोध में अनुरोध को पुनर्निर्देशित करके संभाला जाता है। एक संपत्ति XmlReaderSettings.XmlResolver है जिसका उपयोग इस के लिए किया जा सकता है। अपाचे-लाइसेंस प्राप्त कार्यान्वयन के लिए XMLCatalog.net देखें जिसका उपयोग आप कर सकते हैं।

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

+0

सुझाव के लिए धन्यवाद; मैं यह देखने के लिए प्रयोग करूंगा कि क्या मैं उप-वर्ग 'System.Xml.XmlResolver' का उपयोग करके इसे ठीक कर सकता हूं। – ChrisW

+1

मुझे अब यह काम मिल गया है। मैं पहले विफल रहा था, क्योंकि मैं 'XmlReaderSettings.XmlResolver' संपत्ति को असाइन कर रहा था; लेकिन जब/क्योंकि मैं 'सेटिंग्स.Schemas.Add' का उपयोग कर रहा हूं, इसलिए मुझे 'सेटिंग्स.Schemas.XmlResolver' प्रॉपर्टी को असाइन करने के बजाय इसकी आवश्यकता है। – ChrisW

+1

@ChrisW: मैं भी अपने मूल प्रश्न के रूप में त्रुटि "वैश्विक विशेषता 'http://www.w3.org/XML/1998/namespace:lang' पहले से ही घोषित किया गया है।" प्राप्त हो रही हैं, इसी तरह के कोड के साथ। क्या आपने सेटिंग्स सेट की हैं .chemas.XmlResolver XMLCatalogResolver या कुछ और? मैंने भाग्य के बिना कोशिश की। कोई भी मौका आप अपना कामकाजी कोड पेस्ट कर सकते हैं? – Jeremy