我知道这将是一个重复的问题,但仍然要求再次解决这个问题没有解决办法。让我先解释一下问题陈述,然后我也会提到我的尝试。
XML:
<Order><XMLversion>2</XMLversion><Info>*-first line
*-second line</Info></Order>
CRLF
在“* -first line”语句后面。
我使用Delphi XE4 RAD Studio 工具 - &gt;创建了与此XML对应的 XTR文件。 XML Mapper 实用程序。关注XTR文件后我得到了:
<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>
问题陈述:
在我的dfm文件中,我将 TXMLTransformProvider 和 Clientdataset 。在TXMLTransformProvider中,我提供了XML和XTR文件的路径。 TClientdataset的ProviderName设置为TXMLTransformProvider。
以下是我从XML中读取“info”节点的代码。
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;
XML中有两个字段:XMLVersion和Info。在Clientdataset中,XMLVersion是TStringField,而Info是TMemoField。
ShowMessage(InfoNode),显示如下消息
*-first line&*-second line
对于Delphi 7,它工作正常并显示如下信息:
*-first line
*-second line
以下是我的Dropbox链接,我已针对此问题上传了我的示例项目:
https://www.dropbox.com/s/foi7o3wf7wlx9lh/AmpersandIssue.zip
请注意,我已将XML和XTR文件的硬编码路径放在TXMLTransformProvider中。因此,请将此项目保留在D:驱动器中,或者只更改TXMLTransformProvider中的路径。
以下是EDN链接,我提出了同样的问题,但没有得到回复:
https://forums.embarcadero.com/thread.jspa?messageID=667134򢷾
我尝试过的解决方法:
替换&amp;获得该节点值后,使用#13#10 。
InfoNode:= StringReplace(InfoNode,'&amp;',#13#10,[rfReplaceAll]);
但这不是正确的解决方案,因为信息节点实际上可以包含&amp;在数据库中。
我将XML硬编码为:
<Order><XMLversion>2</XMLversion><Info>*-first line *-second line</Info></Order>
和
<Order><XMLversion>2</XMLversion><Info>*-first line
*-second line</Info></Order>
以及
<Order><XMLversion>2</XMLversion><Info><![CDATA[*-first line
*-second line]]></Info></Order>
没有任何效果。每次我得到的结果与上面提到的相同。 &符号。
Ken White的回答对我来说也不起作用,他在上一个问题中提供了我。
@TLama - 您在上一个问题中建议我(抱歉,但由于某些原因我已将其删除),这是TXMLTransformProvider中的错误和我应该带着雷米的解决方案。但现在没有任何工作。那么我应该采取哪些后续步骤来解决这个直接的问题呢?你有没有用Embarcadero提出这个错误?
请建议我解决此问题的任何解决方法?
答案 0 :(得分:4)
我需要在回答这个问题时说,与Remy或Ken不同,我绝对不是Unicode的专家,我甚至不确定它是否与您的问题有关。
但是,我查看了XMLTransformProvider生成的磁盘上字节,并将其与执行CDS.SaveToFile('Test.Xml',dfXML)时写入磁盘的内容进行了比较。
很明显,CDS会将嵌入在DB备忘录字段中的换行符保存为:


XMLTransformProvider为类似换行生成的内容是:


因此,我的简单建议解决方法是连接到您打开XML数据文件的代码,以便以自己的格式加载带有XML的CDS:
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;
TXMLTransformerProvider或其TXMLTransform子组件中似乎没有任何方便的事件可用作自动调用TestFix的机会。但是,如果你在CDS的AfterOpen事件中调用它似乎工作正常,前提是你在表单中添加了一个“FixingXML”布尔值以防止重新入侵并像这样编码事件:
procedure TfrmAmpersand.ClientDataSet1AfterOpen(DataSet: TDataSet);
begin
if FixingXML then exit;
FixingXML := True;
try
TestFix;
finally
FixingXML := False;
end;
end;
我正在使用XE6,顺便说一句。