AndrewHoward 0 Posted November 16, 2022 (edited) How can I generate this XML ? I am interested in the ab node & the xsi, xsd & MyString <?xml version="1.0"?> <ab xmlns:xsi="https://www.guru99.com/XMLSchema-instance" xmlns:xsd="https://www.guru99.com/XMLSchema" xmlns="MyString"> <founder>Krishna</founder> </abt> This is what I tried: procedure TForm1.Button11Click(Sender: TObject); var MyXMLDocument : IXMLDocument; FounderNode : IXMLNode; begin MyXMLDocument := TXMLDocument.Create(nil); MyXMLDocument.Active := true; MyXMLDocument.DocumentElement := MyXMLDocument.CreateNode('ab', ntElement,''); MyXMLDocument.DocumentElement.DeclareNamespace('xsi', 'https://www.guru99.com/XMLSchema-instance'); MyXMLDocument.DocumentElement.DeclareNamespace('xsd', 'https://www.guru99.com/XMLSchema'); MyXMLDocument.DocumentElement.SetAttributeNS('xmlns', 'MyString',''); FounderNode := MyXMLDocument.DocumentElement.AddChild('founder'); MyXMLDocument.SaveToFile('TestOne01.XML'); MyXMLDocument.Active := false; end; This is what I'm getting: <ab xmlns:xsi="https://www.guru99.com/XMLSchema-instance" xmlns:xsd="https://www.guru99.com/XMLSchema" xmlns=""> <founder/> </ab> why xmlns="MyString" isn't being generated ? Why this is missing ? <?xml version="1.0"?> Thank you Edited November 16, 2022 by AndrewHoward Share this post Link to post
Lajos Juhász 293 Posted November 16, 2022 uses Xml.XMLIntf, Xml.XMLDoc; procedure TForm1.Button1Click(Sender: TObject); var MyXMLDocument : IXMLDocument; FounderNode : IXMLNode; begin MyXMLDocument := TXMLDocument.Create(nil); MyXMLDocument.Active := true; MyXMLDocument.Version:='1.0'; MyXMLDocument.DocumentElement := MyXMLDocument.CreateNode('ab', ntElement,''); MyXMLDocument.DocumentElement.DeclareNamespace('xsi', 'https://www.guru99.com/XMLSchema-instance'); MyXMLDocument.DocumentElement.DeclareNamespace('xsd', 'https://www.guru99.com/XMLSchema'); MyXMLDocument.DocumentElement.SetAttributeNS('xmlns', '','MyString'); FounderNode := MyXMLDocument.DocumentElement.AddChild('founder'); FounderNode.NodeValue:='Krishna'; MyXMLDocument.SaveToFile('TestOne01.XML'); MyXMLDocument.Active := false; end; You have to set the version and MyString should be the 3rd parameter not the second one. 1 Share this post Link to post
AndrewHoward 0 Posted November 16, 2022 Thank you. This is what I got: <?xml version="1.0"?> <ab xmlns:xsi="https://www.guru99.com/XMLSchema-instance" xmlns:xsd="https://www.guru99.com/XMLSchema" xmlns="MyString"> <founder xmlns="">Krishna</founder> </ab> How to get rid of xmlns="" in <founder xmlns="">Krishna</founder> Thank you. Share this post Link to post
Remy Lebeau 1393 Posted November 16, 2022 (edited) 1 hour ago, AndrewHoward said: MyXMLDocument.DocumentElement.SetAttributeNS('xmlns', 'MyString',''); That line should be this instead: MyXMLDocument.DocumentElement.DeclareNamespace('', 'MyString'); Which is equivalent to this: MyXMLDocument.DocumentElement.SetAttributeNS('xmlns', 'http://www.w3.org/2000/xmlns/', 'MyString'); The DeclareNamespace() documentation does not mention that the Prefix parameter can be a blank string, but it is actually supported. This will treat the attribute as an actual namespace declaration in the DOM, even though it doesn't have a prefix assigned. It should also assign the 'MyString' namespace to the DocumentElement since that element doesn't have a prefix assigned, either. Quote FounderNode := MyXMLDocument.DocumentElement.AddChild('founder'); You are creating the element, but you are not assigning any text to it, which is why the element appears as </founder>. You need to add this after calling AddChild(): FounderNode.Text := 'Krishna'; Also, you may or may not need to specify the desired namespace when calling AddChild(), as well (this part I always forget about when exactly a namespace should be specified and when it can be inherited from the parent element - once you start dealing with namespaces in XML, you will find that you need to specify namespaces in add/insert and search operations more often than not): FounderNode := MyXMLDocument.DocumentElement.AddChild('founder', 'MyString'); Edited November 16, 2022 by Remy Lebeau 1 Share this post Link to post
AndrewHoward 0 Posted November 16, 2022 This is what I'm getting: <?xml version="1.0"?> <ab xmlns:xsi="https://www.guru99.com/XMLSchema-instance" xmlns:xsd="https://www.guru99.com/XMLSchema" xmlns="MyString"> <founder xmlns="">Krishna</founder> </ab> Is it possible to have the same as above but the founder node like this:? <founder>Krishna</founder> Thank you. Share this post Link to post
AndrewHoward 0 Posted November 16, 2022 (edited) 3 hours ago, Remy Lebeau said: That line should be this instead: MyXMLDocument.DocumentElement.DeclareNamespace('', 'MyString'); Which is equivalent to this: MyXMLDocument.DocumentElement.SetAttributeNS('xmlns', 'http://www.w3.org/2000/xmlns/', 'MyString'); The DeclareNamespace() documentation does not mention that the Prefix parameter can be a blank string, but it is actually supported. This will treat the attribute as an actual namespace declaration in the DOM, even though it doesn't have a prefix assigned. It should also assign the 'MyString' namespace to the DocumentElement since that element doesn't have a prefix assigned, either. You are creating the element, but you are not assigning any text to it, which is why the element appears as </founder>. You need to add this after calling AddChild(): FounderNode.Text := 'Krishna'; Also, you may or may not need to specify the desired namespace when calling AddChild(), as well (this part I always forget about when exactly a namespace should be specified and when it can be inherited from the parent element - once you start dealing with namespaces in XML, you will find that you need to specify namespaces in add/insert and search operations more often than not): FounderNode := MyXMLDocument.DocumentElement.AddChild('founder', 'MyString'); Is it possible to get exactly this:? <?xml version="1.0"?> <ab xmlns:xsi="https://www.guru99.com/XMLSchema-instance" xmlns:xsd="https://www.guru99.com/XMLSchema" xmlns="MyString"> <founder>Krishna</founder> </ab> I tried different things but I couldn't get this line without xmlns="" : <founder>Krishna</founder> Edited November 16, 2022 by AndrewHoward Share this post Link to post
Remy Lebeau 1393 Posted November 16, 2022 3 hours ago, AndrewHoward said: Is it possible to get exactly this:? Yes. This works for me: procedure TForm1.Button11Click(Sender: TObject); var MyXMLDocument : IXMLDocument; DocElement, FounderNode : IXMLNode; begin MyXMLDocument := NewXMLDocument(); MyXMLDocument.Active := True; DocElement := MyXMLDocument.CreateElement('ab', 'MyString'); MyXMLDocument.DocumentElement := DocElement; // alternatively: // DocElement := MyXMLDocument.AddChild('ab', 'MyString'); DocElement.DeclareNamespace('xsi', 'https://www.guru99.com/XMLSchema-instance'); DocElement.DeclareNamespace('xsd', 'https://www.guru99.com/XMLSchema'); // if this call is present then the 'xmlns=MyString' attribute will be at the end of the element, // but if this is omitted then the attribute will be at the front of the element instead, due to // the earlier CreateElement/AddChild call... DocElement.DeclareNamespace('', 'MyString'); FounderNode := DocElement.AddChild('founder'); FounderNode.Text := 'Krishna'; MyXMLDocument.SaveToFile('TestOne01.XML'); end; It is important that the 'ab' element actually have the 'MyString' namespace assigned to it, so that any child nodes can inherit it. When an `xmlns` attribute appears on a child node, it means the namespace was not inherited correctly. 1 Share this post Link to post