2012-05-27 25 views
6

जब मैं एक DTD के साथ एक XML दस्तावेज़ (ईगल फ़ाइल) पढ़ने की कोशिश मैं त्रुटि मिलती है:सी ++ बिल्डर XE2, TXMLDocument 'DTD निषिद्ध है'

Project xx raised exception class EDOMParserError with message 'DTD is prohibited'

एक्सएमएल हेडर कुछ इस तरह दिखता है:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE eagle SYSTEM "eagle.dtd"> 

अगर मैं दूसरी पंक्ति को हटा दें ...

<!DOCTYPE eagle SYSTEM "eagle.dtd"> 

... सब कुछ ठीक काम करता है।

कुछ googling के बाद ऐसा लगता है कि एमएसएक्सएमएल पार्सर के पास'prohibitDTD 'नामक एक विकल्प है जिसे डिफ़ॉल्ट रूप से सत्य पर सेट किया गया है (पुराने संस्करणों में यह गलत था)।

हालांकि यह विकल्प TXMLDocument क्लास से झूठी पर सेट करना संभव नहीं है। एक समाधान .pas लाइब्रेरी का एक पुनर्मूल्यांकन या CoCreateInstance() के साथ अपने आप को इंटरफ़ेस बनाने के लिए प्रतीत होता है।

मैंने देखा है कि सभी उदाहरण डेल्फी में हैं और मुझे सी ++ बिल्डर को ट्रान्सनल करने के लिए भिन्नताएं हैं।

क्या कोई जानता है कि सी ++ बिल्डर XE2 के साथ एक डीटीडी एक्सएमएल दस्तावेज़ कैसे पढ़ा जाए?

मेरे उदाहरण कोड ...

#include <xmldoc.hpp> 

_di_IXMLNode XMLObject; 

TXMLDocument *XMLDocument = new TXMLDocument(this); 
XMLDocument->LoadFromFile(fileName); // <----- Exception EDOMParserError 
XMLObject = XMLDocument->DocumentElement; 

धन्यवाद ...

उत्तर

5

XE2 ने इस समस्या का मूल समाधान प्रस्तुत किया: वैरिएबल MSXML6_ProhibitDTDXml.Win.msxmldom.hpp में घोषित किया गया है। आप डेटा लोड करने से पहले false के लिए सेट कर सकते हैं TXMLDocument में:

#include <xmldoc.hpp> 
#include <msxmldom.hpp> 

MSXML6_ProhibitDTD = false; 
TXMLDocument *XMLDocument = new TXMLDocument(this): 
XMLDocument->LoadFromFile(fileName); 
_di_IXMLNode XMLObject = XMLDocument->DocumentElement; 

एक तरफ ध्यान दें पर: यह आम तौर पर एक अच्छा विचार गतिशील इस तरह TXMLDocument उदाहरण बना करने के लिए नहीं है।यह बजाय IXMLDocument इंटरफेस का उपयोग करने के लिए बेहतर है:

के रूप में:

#include <xmldoc.hpp> 
#include <msxmldom.hpp> 

MSXML6_ProhibitDTD = false; 
_di_IXMLDocument XMLDocument = LoadXMLDocument(fileName); 
_di_IXMLNode XMLObject = XMLDocument->DocumentElement; 
+0

धन्यवाद यह एक आकर्षण की तरह काम करता है! अजीब बात यह है कि जानकारी का यह टुकड़ा ढूंढना इतना कठिन होना चाहिए ... IXMLDocument TXMLDocument से बेहतर क्यों है? जैसा कि मैंने समझा, IXMLDocument TXMLDocument का एक हिस्सा है। –

+0

'TXMLDocument'' IXMLDocument' इंटरफ़ेस लागू करता है, इसलिए इसकी एक ही कार्यक्षमता है। हालांकि, यदि आप 'NULL' स्वामी के साथ' TXMLDocument' को गतिशील रूप से तत्काल करते हैं (जिसे आपको अल्पकालिक एक्सएमएल ऑब्जेक्ट्स बनाते समय करना चाहिए), यह संदर्भ-गणना ऑब्जेक्ट के रूप में कार्य करता है। यह दस्तावेज व्यवहार है। 'TXMLDocument'' वैरिएबल को 'TXMLDocument * 'चर के गतिशील उदाहरण को असाइन करना सुरक्षित नहीं है जब तक कि उसके पास कोई स्वामी असाइन नहीं किया जाता है। अन्यथा, संदर्भ संदर्भ को सही तरीके से बनाए रखने के लिए आपको इसे '_di_IXMLDocument' चर में असाइन करना होगा। –

+0

स्पष्टीकरण के लिए धन्यवाद। मेरे मामले में TXMLDocument * के गतिशील उदाहरण में हमेशा एक मालिक होता है और पूरे एप्लिकेशन के माध्यम से रहता है। मेरे पास पहले से प्रोजेक्ट कोड TXMLDocument के साथ काम कर रहा है, इसलिए मैं इसे पुराने कोड का पुन: उपयोग करने के लिए सुविधा से बाहर उपयोग करता हूं। –

0

आप अपने प्रोजेक्ट फ़ोल्डर में MSXMLDOM.pas प्रतिलिपि बनाएँ, और इस समस्या को ठीक करने के लिए उसे बदलने की जरूरत है।

निम्नलिखित में function TMSDOMDocument.GetMSDocument के कार्यान्वयन को बदलें, और फिर अपनी परियोजना का पुनर्निर्माण करें।

नोट ProhibitDTDProhibitDTD प्रकाशित नहीं होने के बजाय आपको IXMLDOMDocument2.setProperty का उपयोग सीधे का उपयोग करना है।

function TMSDOMDocument.GetMSDocument: IXMLDOMDocument; 
var 
    Doc2: IXMLDOMDocument2; 
begin 
    Result := MSNode as IXMLDOMDocument; 
    if Supports(Result, IXMLDOMDocument2, Doc2) then 
     Doc2.setProperty('ProhibitDTD', False); 
end; 

ध्यान दें कि यह केवल कार्य करेगा जब आप क्रम संकुल के साथ निर्माण नहीं कर रहे हैं!

यह समाधान टीमबी के सदस्य द्वारा बनाई गई एम्बरकेडेरो फ़ोरम पोस्ट से है; मुझे इसे पढ़ना याद आया, और इसे CodeNewsFast के माध्यम से उन मंचों की खोज में मिला - ईएमबीटी मंचों पर खोज कार्यक्षमता ने कभी भी अच्छा काम नहीं किया है, और हाल ही में पुनर्निर्माण या रीइंडेक्स या कुछ ने इसे पहले से भी बदतर बना दिया है। :-)

+0

मैं TeamB सदस्य जो चर्चा की कर रहा हूँ ईएमबीटी मंचों में यह कामकाज। यह कामकाज केवल XE और पहले की आवश्यकता है। XE2 ने इस सटीक समस्या का मूल समाधान प्रस्तुत किया। मेरा जवाब देखें –

+0

हाँ, @ रेमी। मुझे पता है। यही कारण है कि मैंने उस खोज को लिंक पोस्ट किया जिसे मैंने प्राप्त किया; इसलिए लोगों को पता चलेगा कि मैं समाधान के साथ आने के लिए क्रेडिट नहीं ले रहा था। :-) –

1

वैश्विक चर MSXML6_ProhibitDTD साथ वैकल्पिक हल के बाद से हटा दिया गया है और मैं इसे XE5 के साथ या तो काम करने के लिए नहीं मिल सका है, यहाँ एक और समाधान है documentation में कहा गया है, वहाँ

Xml.Win.Msxmldom.MSXMLDOMDocumentFactory.AddDOMProperty 

दुर्भाग्य से डोम संपत्ति को बदलने के लिए इस पद्धति है यह है तो यह ...

उपयोग करने के लिए तुच्छ नहीं

#include <Xml.Win.msxmldom.hpp> 

Foo::Foo() 
{ 
    //change the dom property in your constructor. 
    ((TMSXMLDOMDocumentFactory*)Xml::Win::Msxmldom::MSXMLDOMDocumentFactory)->AddDOMProperty("ProhibitDTD", False, true); 
} 

और उपयोग इस विधि:

इस नाम स्थान के लिए शीर्ष लेख शामिल हैं। (। डाली आवश्यक है, क्योंकि MSXMLDOMDocumentFactory अपने आप में एक metaclass इंटरफ़ेस से प्राप्त होती है या तो मैं अवधारणा के पीछे मिला नहीं है।)

एक डेल्फी ब्लॉग से प्रेरित: https://bobsotherblog.wordpress.com/2013/09/19/fixing-dtd-is-prohibited-error-in-delphi/