I know its going to be a repeating question but still asking again as no workaround worked for this problem. Let me explain the problem statement first and then I will also mention what I tried.
XML:
<Order><XMLversion>2</XMLversion><Info>*-first line
*-second line</Info></Order>
CRLF
is there after "*-first line" statement.
I created XTR file corresponding to this XML using Delphi XE4 RAD Studio Tools --> XML Mapper utility. Following XTR file I got:
<XmlTransformation Version="1.0"><Transform Direction="ToCds"><SelectEach dest="DATAPACKET\ROWDATA\ROW" from="\Order"><Select dest="@XMLversion" from="\XMLversion"/><Select dest="@Info" from="\Info"/></SelectEach></Transform><XmlSchema RootName="Order"><![CDATA[<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<element xmlns="http://www.w3.org/2001/XMLSchema" name="Order" type="OrderType"/>
<complexType xmlns="http://www.w3.org/2001/XMLSchema" name="OrderType">
<sequence>
<element name="XMLversion" type="XMLversionType"/>
<element name="Info" type="InfoType"/>
</sequence>
</complexType>
<element xmlns="http://www.w3.org/2001/XMLSchema" name="XMLversion" type="XMLversionType"/>
<simpleType xmlns="http://www.w3.org/2001/XMLSchema" name="XMLversionType">
<restriction base="xs:string"/>
</simpleType>
<element xmlns="http://www.w3.org/2001/XMLSchema" name="Info" type="InfoType"/>
<simpleType xmlns="http://www.w3.org/2001/XMLSchema" name="InfoType">
<restriction base="xs:string"/>
</simpleType>
</xs:schema>]]></XmlSchema><CdsSkeleton/><XslTransform/><Skeleton><![CDATA[<?xml version="1.0"?><DATAPACKET Version="2.0"><METADATA><FIELDS><FIELD attrname="XMLversion" fieldtype="string" WIDTH="1"/><FIELD attrname="Info" fieldtype="bin.hex" SUBTYPE="Text"/></FIELDS><PARAMS/></METADATA><ROWDATA/><METADATA><FIELDS><FIELD attrname="XMLversion" fieldtype="string" WIDTH="1"/><FIELD attrname="Info" fieldtype="bin.hex" SUBTYPE="Text"/></FIELDS><PARAMS/></METADATA><ROWDATA/></DATAPACKET>
]]></Skeleton></XmlTransformation>
Problem Statement:
In my dfm file, I put TXMLTransformProvider and Clientdataset. In TXMLTransformProvider, I have provided the path of XML and XTR files. ProviderName of TClientdataset is set to TXMLTransformProvider.
Following is my code to read "info" node from the XML.
procedure TfrmAmpersand.Issue;
var
InfoNode : Variant;
begin
try
InfoNode := ClientDataset1.FieldByName('Info').AsVariant;
ShowMessage(InfoNode);
except on e:exception do
begin
ShowMessage(e.Message);
end;
end;
end;
There are two fields in XML: XMLVersion and Info. In Clientdataset, XMLVersion is TStringField while Info is of TMemoField.
ShowMessage(InfoNode), shows the message like this
*-first line&*-second line
While in case of Delphi 7, it works fine and shows message like this:
*-first line
*-second line
Following is my dropbox link where I have uploaded my sample project for this problem:
https://www.dropbox.com/s/foi7o3wf7wlx9lh/AmpersandIssue.zip
Please note, I have put hardcoded path for XML and XTR file in TXMLTransformProvider. So keep this project in D: drive or just change the path in TXMLTransformProvider.
Following is EDN link where I have asked same question but got no reply:
https://forums.embarcadero.com/thread.jspa?messageID=667134򢷾
Workarounds I tried:
Replace & with #13#10 after getting that node value.
InfoNode := StringReplace(InfoNode, '&', #13#10, [rfReplaceAll]);
But this is not the right solution as info node can actually contain the & in database.
I hardcoded my XML as:
<Order><XMLversion>2</XMLversion><Info>*-first line *-second line</Info></Order>
and
<Order><XMLversion>2</XMLversion><Info>*-first line
*-second line</Info></Order>
and also
<Order><XMLversion>2</XMLversion><Info><![CDATA[*-first line
*-second line]]></Info></Order>
Nothing worked. Everytime I am getting the same result which I mentioned above. The ampersand sign.
Ken White's answer is also not working for me which he provided me in last question.
@TLama - You suggested me in my previous question (sorry, but I have deleted that for some reason) that this is bug in TXMLTransformProvider and I should carry with Remy's solution. But now nothing is working. So what next steps should I take to solve this straight forward problem? Have you raised this bug with Embarcadero?
Please suggest me any workaround which can solve this issue?
I need to preface this answer by saying that unlike Remy or Ken, I am absolutely no expert at Unicode, and I'm not even sure that it's involved in your problem.
However I've looked at the on-disk bytes that your XMLTransformProvider generates and compared it with what gets written to disk when you do a CDS.SaveToFile('Test.Xml', dfXML).
It's evident that whereas a CDS saves a newline embedded in a DB memo field as:


what the XMLTransformProvider produces for a similar newline is:


So, my simple-minded suggested work-around is to wire in to your code where you open the XML datafile something like this, to load the CDS with XML in its own format:
const
TransformNewLine = '
';
CDSNewLine = '
';
function FixCdsXml(Input : String) : String;
begin
Result:= StringReplace(Input, TransformNewLine, CDSNewLine, [rfReplaceAll]);
end;
procedure TfrmAmpersand.TestFix;
var
S : String;
SS : TStringStream;
begin
S := XMLTransformProvider1.TransformRead.Data;
S := FixCdsXml(S);
SS := TStringStream.Create(S);
try
SS.Position := 0;
ClientDataSet1.LoadFromStream(SS);
finally
SS.Free;
end;
end;
There don't seem to be any convenient events in TXMLTransformerProvider or its TXMLTransform sub-components to use as an opportunity to call TestFix automatically. However, it does seem to work ok if you call it in the CDS's AfterOpen event, provided you add a "FixingXML" boolean to your form to prevent re-entrancy and code the event like this:
procedure TfrmAmpersand.ClientDataSet1AfterOpen(DataSet: TDataSet);
begin
if FixingXML then exit;
FixingXML := True;
try
TestFix;
finally
FixingXML := False;
end;
end;
I'm using XE6, btw.