2009-10-07 7 views
8

का उपयोग कर एक XML दस्तावेज़ बनाने का समस्या मैं डेल्फी के लिए नया हूं और अब मुझे एक XML बनाने के लिए पढ़ना है।TXMLDocument

function foo.createXMLDocument(): TXMLDocument; 
var 
    res: TXMLDocument; 
    rootNode: IXMLNode; 
    sl : TStringList; 
begin 
    res := TXMLDocument.Create(nil); 
    res.Active := true; 
    rootNode := res.AddChild('label'); 
    // create string for debug purposes 
    sl := TStringList.Create; 
    sl.Assign(res.XML);// sl is empty after this assignment 
    //add more elements 
    generateDOM(rootNode); 

    Result := res; 
end; 

समस्या है, बच्चे की गिनती नोड्स बढ़ जाती है लेकिन res.XML खाली है: मेरी कोड निम्नलिखित है। उल्लेख नहीं है कि जेनरोड प्रक्रिया में शेष तत्व कुछ भी नहीं कर रहे हैं। मैं आपकी मदद से बहुत खुश हूं।

+0

अच्छा होगा। डी 2007 के मामले में मेरा जवाब देखें। –

उत्तर

12

अस्वीकरण: डी 2007 के साथ परीक्षण किया गया।

आपका कोड वास्तव में एक्सएमएल पैदा नहीं करता (<label/>) इस संशोधित समारोह में दिखाया गया है:

function createXMLDocument(): TXMLDocument; 
var 
    res: TXMLDocument; 
    rootNode: IXMLNode; 
    sl : TStringList; 
begin 
    res := TXMLDocument.Create(nil); 
    res.Active := true; 
    rootNode := res.AddChild('label'); 
    // create string for debug purposes 
    sl := TStringList.Create; // not needed 
    sl.Assign(res.XML); // Not true: sl is empty after this assignment 
    ShowMessage(sl.text);// sl is NOT empty! 
    sl.Free;    // don't forget to free it! use try..finally.. to guarantee it! 
    //add more elements 
// generateDOM(rootNode); 
    Result := res; 
end; 

लेकिन यह टिप्पणी के बहुत के लिए कहता है:
- आप एक की जरूरत नहीं है स्थानीय res वैरिएबल, बस परिणाम का उपयोग करें।
- आपको एक्सएमएल देखने के लिए अतिरिक्त स्ट्रिंगलिस्ट की आवश्यकता नहीं है: Result.Xml.Text
- स्ल स्ट्रिंगलिस्ट को भूलें यदि आप एक बनाते हैं।
- आपके द्वारा वापस किए गए XmlDocument फ़ंक्शन के बाहर अनुपयोगी है और यदि आप आज़माते हैं तो एवी देता है।

क्यों?
क्योंकि एक XmlDocument एक इंटरफ़ेस अन्यथा के रूप में, क्रम में अपनी जीवन प्रबंधन के लिए एक मालिक
साथ के रूप में एक घटक इस्तेमाल किया जा करने का इरादा है, या यह है।
तथ्य यह है कि आप rootNode को पकड़ने के लिए इंटरफ़ेस का उपयोग करते हैं, इसे CreateXmlDocument फ़ंक्शन के अंत में नष्ट कर दिया जाता है। और यदि आप TXMLNode._Release में कोड देखते हैं, तो आप देखेंगे कि यह TXMLDocument._Release ट्रिगर्स करता है जो एक्सएमएल डॉक्यूमेंट (या इसके संदर्भ में एक इंटरफ़ेस रखने वाला इंटरफ़ेस) के मालिक होने तक नष्ट हो जाता है।
यही कारण है कि XMLDocument CreateXMLDocument फ़ंक्शन के अंदर मान्य और पॉप्युलेट किया गया है लेकिन इसके बाहर उपलब्ध नहीं है जब तक आप इंटरफ़ेस वापस नहीं करते हैं या कोई मालिक प्रदान नहीं करते हैं।

नीचे वैकल्पिक समाधान देखें: अगर आप डेल्फी संस्करण उपयोग कर रहे प्रदान की

function createXMLDocumentWithOwner(AOwner: TComponent): TXMLDocument; 
var 
    rootNode: IXMLNode; 
begin 
    Assert(AOwner <> nil, 'createXMLDocumentWithOwner cannot accept a nil Owner'); 
    Result := TXMLDocument.Create(AOwner); 
    Result.Active := True; 
    rootNode := Result.AddChild('label'); 
    OutputDebugString(PChar(Result.Xml.Text)); 
    //add more elements 
// generateDOM(rootNode); 
end; 

function createXMLDocumentInterface(): IXMLDocument; 
var 
    rootNode: IXMLNode; 
begin 
    Result := TXMLDocument.Create(nil); 
    Result.Active := True; 
    rootNode := Result.AddChild('label'); 
    OutputDebugString(PChar(Result.Xml.Text)); 
    //add more elements 
// generateDOM(rootNode); 
end; 


procedure TForm7.Button1Click(Sender: TObject); 
var 
    doc: TXmlDocument; 
    doc2: IXMLDocument; 
begin 
    ReportMemoryLeaksOnShutdown := True; 

    doc := createXMLDocument; 
    // ShowMessage(doc.XML.Text); // cannot use it => AV !!!! 
    // already freed, cannot call doc.Free; 

    doc := createXMLDocumentWithOwner(self); 
    ShowMessage(doc.XML.Text); 

    doc2 := createXMLDocumentInterface; 
    ShowMessage(doc2.XML.Text); 
end; 
2

मेरे समान कार्यान्वयन में, मैं TXMLDocument के बजाय IXMLDocument के रूप में res घोषित करता हूं।

var 
    XMLDoc: IXMLDocument; 
. 
. 
    XMLDoc := TXMLDocument.Create(nil); 
    XMLDoc.Active := True; 
. 
. 
    XMLDoc.SaveToFile(Filename); 
    XMLDoc.Active := False; 
+0

हालांकि मालिक घटक के बिना TXmlDocument को तत्काल करने पर यह सही काम है, लेकिन यह समस्या के लिए अप्रासंगिक है। –

4

TXMLDocument.AddChild विधि के Delphi Help कहते हैं (नीचे):

टिप्पणी: इस दस्तावेज़ का दस्तावेज़ तत्व को एक बच्चे को जोड़ने के लिए addChild फोन न करें। XML दस्तावेज़ में डेटा जोड़ते समय, दस्तावेज़ तत्व के AddChild विधि या पदानुक्रम में नोड का उपयोग करें जो नए नोड के माता-पिता होना चाहिए।

और यह वही है जो आप सही कर रहे हैं? :-)

यहाँ Delphi XML Document Programming बारे में एक परिचय लेख है और दिखाता है कि आप TXMLDocument.DocumentElement संपत्ति अपने कोड में rootnode चर की अपनी परिभाषा के बजाय के साथ काम कर सकते हैं।

+0

आपके द्वारा उद्धृत परिचय यह दर्शाता है कि स्क्रैच से नया दस्तावेज़ कैसे बनाएं। न तो सहायता पृष्ठ। प्रश्न में कोड को सही बनाने के लिए कैसे बदलना चाहिए? –

+0

D2007 TXmlDocument.AddChild में दस्तावेज़ नोड बनाता है यदि पहले से नहीं है और इसके AddChild को कॉल करता है। तो यह समस्या नहीं है। –

+0

इरविन, आप अपना जवाब संपादित करते हैं, लेकिन मुझे नहीं लगता कि आपने मेरी टिप्पणी को संबोधित किया है। –