Note that there are some explanatory texts on larger screens.

plurals
  1. PODelphi Exception when Preserving Whitespace in TXMLDocument
    primarykey
    data
    text
    <p><strong>This is a follow up to my earlier post: <a href="https://stackoverflow.com/questions/16743380/string-to-xmlnode-delphi-or-how-to-add-an-xml-fragment-to-txmldocument">String to XmlNode Delphi (or how to add an xml fragment to TXMLDocument)</a> It seemed appropriate to start a new question...</strong> </p> <p>I am essentially adding well formed xml snippets to an existing xmldocument. The code suggested in the previous solution had been working great - until - I added [poPreserveWhiteSpace] to TXMLDocument.ParseOptions. </p> <p>When I remove [poPreserveWhiteSpace] everything works fine, but whitespace is not preserved. It actually puts the closing tag on a new line. </p> <p>Here is a code snippet ot the Target TXMLDocument.</p> <pre><code> StoredXMLObj := TXMLDocument.Create(self); StoredXMLObj.Options := [doNodeAutoCreate, doNodeAutoIndent]; StoredXMLObj.ParseOptions := StoredXMLObj.ParseOptions + [poPreserveWhiteSpace]; StoredXMLObj.XML.Assign(StoredXML); //StoredXML is a TStringList with a complete XML Document StoredXMLObj.Active := TRUE; </code></pre> <p>I have tried different combinations of the Options and ParseOptions above, but I can only get the code to work by removing [poPreserveWhiteSpace].</p> <p>The code that triggers the exception is the second line of:</p> <pre><code>tmpNode := storedXMLObj.DocumentElement.ChildNodes[i]; // &lt;Class&gt; node tmpNode.ChildNodes.Nodes[1].ChildNodes.Nodes[0].ChildNodes.Add(LoadXMLData(MissingElements[j]).DocumentElement); //TMPNode is an IXMLNode and MissingElements is a TStringList </code></pre> <p>I tried creating a reference to the return value of LoadXMLData(..), and setting those ParseOptions to match, before adding the xml snippet, but no luck there either.</p> <p>Any thoughts?</p> <p><strong>Edit: Adding self contained sample code to demonstrate problem. Clarified Title.</strong> Here is some simplified code. Note that there will be an exception unless you comment out the line containing [poPreserveWhitespace]. **Edit2: Tweaking code to preserve whitespace as per Remy's suggestion. Still has problem when calling FormatXMLData.</p> <pre><code>procedure TForm2.BitBtn2Click(Sender: TObject); var FragmentXMLObj : TXMLDocument; StoredXMLObj : TXMLDocument; FragNode : IXMLNode; //THIS SHOULD BE IXMLNODE, RIGHT? XMLStarting, XMLFragment, XMLMerged : TStringList; i : integer; begin //StringLists to hold xml data XMLStarting := TStringList.Create; //COMPLETE XML XMLFragment := TStringList.Create; //XML FRAGMENT TO INSERT INTO COMPLETE XML XMLMerged := TStringList.Create; //MERGE OF THE ABOVE TWO. //STARTING XML XMLStarting.Add('&lt;?xml version="1.0" encoding="UTF-16" standalone="no"?&gt;'); XMLStarting.Add('&lt;Programs&gt;'); XMLStarting.Add(' &lt;Program_Group Batch_No="{12345678-1234-1234-1234-123456789ABC}" Description="FOO_824_1"&gt;'); XMLStarting.Add(' &lt;Program Name="PROG_1"&gt;'); XMLStarting.Add(' &lt;Class Name="CLASS_1"&gt;'); XMLStarting.Add(' &lt;Property Name="DB" RttiType="tkString"&gt; &lt;/Property&gt;'); XMLStarting.Add(' &lt;Property Name="SystemDate" RttiType="tkClass" ClassType="TXSDATE"&gt;12/30/1899&lt;/Property&gt;'); XMLStarting.Add(' &lt;/Class&gt;'); XMLStarting.Add(' &lt;/Program&gt;'); XMLStarting.Add(' &lt;/Program_Group&gt;'); XMLStarting.Add('&lt;/Programs&gt;'); //XML DOCUMENT OBJECT StoredXMLObj := TXMLDocument.create(self); //PROBLEM LINE START StoredXMLObj.ParseOptions := StoredXMLObj.ParseOptions + [poPreserveWhiteSpace]; //PROBLEM LINE END StoredXMLObj.Options := [doNodeAutoCreate, doNodeAutoIndent]; StoredXMLObj.XML.Text := XMLStarting.Text; StoredXMLObj.Active := TRUE; //XML FRAGMENT WITH SPACES XMLFragment.Add('&lt;ParentNode&gt;'); XMLFragment.Add('&lt;Property Name="VRSN" RttiType="tkString"&gt; &lt;/Property&gt;'); XMLFragment.Add('&lt;Property Name="ShowMetaData" RttiType="tkBoolean"&gt; &lt;/Property&gt;'); XMLFragment.Add('&lt;/ParentNode&gt;'); //--OLD CODE THAT RAISES EXCEPTION-- //INSERTING XML FRAGMENT INTO STARTING XML // FragNode := storedXMLObj.DocumentElement.ChildNodes[0]; // FragNode.ChildNodes.Nodes[0].ChildNodes.Nodes[0].ChildNodes.Add(LoadXMLData(XMLFragment.Text).DocumentElement.ChildNodes.Nodes[0]); // FragNode.ChildNodes.Nodes[0].ChildNodes.Nodes[0].ChildNodes.Add(LoadXMLData(XMLFragment.Text).DocumentElement.ChildNodes.Nodes[1]); //--OLD CODE THAT RAISES EXCEPTION-- FragNode := storedXMLObj.DocumentElement.ChildNodes[1]; FragmentXMLObj := TXMLDocument.Create(self); FragmentXMLObj.ParseOptions := FragmentXMLObj.ParseOptions + [poPreserveWhiteSpace]; FragmentXMLObj.Options := [doNodeAutoCreate, doNodeAutoIndent]; FragmentXMLObj.LoadFromXML(XMLFragment.Text); //FragNode.ChildNodes.Nodes[1].ChildNodes.Nodes[1].ChildNodes.Add(FragmentXMLObj.DocumentElement); //this also pulls in the parent tags, which I don't want. for i := 0 to FragmentXMLObj.DocumentElement.ChildNodes.Count-1 do //easier to just pull in all the nodes (including whitespace, then formatxml to cleanup). FragNode.ChildNodes.Nodes[1].ChildNodes.Nodes[1].ChildNodes.Add(FragmentXMLObj.DocumentElement.ChildNodes.Nodes[i]); FragmentXMLObj.Free; XMLMerged.Text := StoredXMLObj.XML.Text; XMLMerged.Text := FormatXMLData(XMLMerged.Text); //UGH... FormatXMLData WIPES OUT WHITESPACE PROPERTY VALUES!! Doesn't seem to have any settings either... XMLMerged.SaveToFile('c:\merged.xml'); XMLStarting.Free; XMLFragment.Free; XMLMerged.Free; StoredXMLObj.Free; end; </code></pre> <p>The Resulting Merged XML File... Whitespace property values got wiped out during formatting (and I do need to format the data, otw it is REALLY ugly). </p> <pre><code>&lt;?xml version="1.0" encoding="UTF-16" standalone="no"?&gt; &lt;Programs&gt; &lt;Program_Group Batch_No="{12345678-1234-1234-1234-123456789ABC}" Description="FOO_824_1"&gt; &lt;Program Name="PROG_1"&gt; &lt;Class Name="CLASS_1"&gt; &lt;Property Name="DB" RttiType="tkString"/&gt; &lt;Property Name="SystemDate" RttiType="tkClass" ClassType="TXSDATE"&gt;12/30/1899&lt;/Property&gt; &lt;Property Name="VRSN" RttiType="tkString"/&gt; &lt;Property Name="ShowMetaData" RttiType="tkBoolean"/&gt; &lt;/Class&gt; &lt;/Program&gt; &lt;/Program_Group&gt; &lt;/Programs&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload