5

I Have a few text strings that contain well formed XML.

I would like to be able to (1) turn these strings into IXMLNodes then (2) append them to an existing XMLDocument. Preferably without declaring a new XMLDocument first.

This doesn't seem possible?

Is there any easy way to accomplish something equivalent though? My initial thought was to use the IXMLNode.XML (string) property and insert the new strings. No such luck as IXMLNode.XML is Read Only.

Here is an example, if I had the following strings in a TStringList,

<Property Name="Version" RttiType="tkString"></Property>
<Property Name="ShowSubunit" RttiType="tkBoolean"></Property>

And I had the following XML, already loaded into a TXMLDocument, how could I easily append the two lines above into the TXMLDocument below?

<Program Name="PFOO">
  <Class Name="CFOO">
    <Property Name="DBN" RttiType="tkString"/>
    <Property Name="SDate" RttiType="tkClass" ClassType="TXSDATE">12/30/1899</Property>
    <Property Name="XForm" RttiType="tkEnumeration">xfXML</Property>
    <Property Name="Singleton" RttiType="tkBoolean">True</Property>
  </Class>
</Program>

Any other (simple) ways to achieve this (no protected hack on the XML property please)?

Thank you!

Ken White
  • 123,280
  • 14
  • 225
  • 444
sse
  • 987
  • 1
  • 11
  • 30

2 Answers2

2

Unless you parse the XML fragments manually and then construct the relevant child nodes/attributes manually, you will have to load the fragments into a temp XMLDocument and then move its nodes to the main XMLDocument as needed.

Update: For example:

Node := XmlDocument1.DocumentElement.ChildNodes[0]; // <Class> node
Node.ChildNodes.Add(LoadXMLData('<Property Name="Version" RttiType="tkString"></Property>').DocumentElement);
Node.ChildNodes.Add(LoadXMLData('<Property Name="ShowSubunit" RttiType="tkBoolean"></Property>').DocumentElement);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • This may indeed be the only way to go. Might you be able to provide me with a simple example? – sse May 28 '13 at 14:07
  • Just an fyi, I did try myself, but get 'Property or Method "importNode" is not supported by DOM Vendor "MSXML"' – sse May 28 '13 at 16:21
  • Here is the code I tried: currProgNode.DOMNode.ownerDocument.importNode(lclXMLObj.Node.DOMNode,true); (where lclXMLObj is of type TXMLDocument and currProgNode is of type IXMLNode, basically trying to copy nodes across XML Docs as suggested). I really feel that this should be much easier. I hope I am missing something obvious. Thank you again. – sse May 28 '13 at 16:25
  • You don't need to drop down to the DOM level to move nodes between documents. Simply `Add()` or `Insert()` an `IXMLNode` into the `ChildNodes` of another `IXMLNode` and it will automatic move to the new document if needed. I updated my answer with an example. – Remy Lebeau May 28 '13 at 21:13
  • Thank you for the redirection (and the answer!). I wasted much time at the DOM level. – sse May 29 '13 at 04:13
0

Check out SimpleStorage. For now its tied to OmniXML, but its powerfull. What you want would look like this:

CurrentNode.Append(StorageFromXML('<Node>Content</Node>'));

One line of code.

Runner
  • 6,073
  • 26
  • 38
  • Thank you. It's a wonderfully simple approach, unfortunately, I am limited to TXMLDocument or MSXML directly. Any other thoughts? – sse May 28 '13 at 14:11
  • I see you found the solution. It is unfortunately the only viable way in your case. Vanila XML is so clumsy to work with, that is why I made SimpleStorage. When I will have some time I plan to expand it and make it compatible with just about any structured storage out there :) – Runner May 29 '13 at 16:31