我正在基于Bob Swart's "Delphi XE2 XML, SOAP & Web Services Development" book的文档对XML文档进行XSL转换 使用表单上的TXSLPageProducer,这可以正常工作:
procedure TFrmRemoveNamespaces.Button1Click(Sender: TObject);
const
cRemoveNSTransform =
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' +
'<xsl:output method="xml" indent="no"/>' +
'<xsl:template match="/|comment()|processing-instruction()">' +
' <xsl:copy>' +
' <xsl:apply-templates/>' +
' </xsl:copy>' +
'</xsl:template>' +
'<xsl:template match="*">' +
' <xsl:element name="{local-name()}">' +
' <xsl:apply-templates select="@*|node()"/>' +
' </xsl:element>' +
'</xsl:template>' +
'<xsl:template match="@*">' +
' <xsl:attribute name="{local-name()}">' +
' <xsl:value-of select="."/>' +
' </xsl:attribute>' +
'</xsl:template>' +
'</xsl:stylesheet>';
// From http://wiki.tei-c.org/index.php/Remove-Namespaces.xsl
// This is a quick XSLT script for removing the namespaces from any document. It will remove the prefix as well.
var
SS: TStringStream;
TS: TStringList;
XMLDoc: TXMLDocument;
XSLPP: TXSLPageProducer;
begin
XMLDoc := TXMLDocument.Create(self);
XMLDoc.active := false;
MmoAfter.Clear;
SS := TStringStream.Create('',TEncoding.UTF8);
SS.Position := 0;
MmoBefore.Lines.SaveToStream(SS);
SS.Position := 0;
XMLDoc.LoadFromStream(SS);
SS.Free;
TS := TStringList.Create;
TS.Text := cRemoveNSTransform;
XSLPP := TXSLPageProducer.Create(self);
XSLPP.XML := TS;
XSLPP.XMLData := XMLDoc;
XMLDoc.active := true;
MmoAfter.Text := XSLPP.Content;
TS.Free;
XMLDoc.Free;
XSLPP.Free;
end;
但是,如果我将代码移动到一个单独的单元中的类辅助函数,我会在“Result:= XSLPP.Content”上得到一个无效的指针操作。
调用代码只是“MmoAfter.Text:= TXMLHelper.RemoveNameSpaces(MmoBefore.Text);”使用此代码构成类助手单元:
class function TXMLHelper.RemoveNameSpaces(XMLString: String): String;
const
// An XSLT script for removing the namespaces from any document. It will remove the prefix as well.
// From http://wiki.tei-c.org/index.php/Remove-Namespaces.xsl
cRemoveNSTransform =
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' +
'<xsl:output method="xml" indent="no"/>' +
'<xsl:template match="/|comment()|processing-instruction()">' +
' <xsl:copy>' +
' <xsl:apply-templates/>' +
' </xsl:copy>' +
'</xsl:template>' +
'<xsl:template match="*">' +
' <xsl:element name="{local-name()}">' +
' <xsl:apply-templates select="@*|node()"/>' +
' </xsl:element>' +
'</xsl:template>' +
'<xsl:template match="@*">' +
' <xsl:attribute name="{local-name()}">' +
' <xsl:value-of select="."/>' +
' </xsl:attribute>' +
'</xsl:template>' +
'</xsl:stylesheet>';
var
SS: TStringStream;
TS: TStringList;
XSLPP: TXSLPageProducer;
XMLDoc : TXMLDocument;
begin
XMLDoc := TXMLDocument.Create(nil);
// XMLDoc.active := true;
SS := TStringStream.Create(XMLString,TEncoding.UTF8);
SS.Position := 0;
XMLDoc.LoadFromStream(SS);
SS.Free;
TS := TStringList.Create;
TS.Text := cRemoveNSTransform;
XSLPP := TXSLPageProducer.Create(nil);
XSLPP.DOMVendor := GetDOMVendor('MSXML');
XSLPP.XML := TS;
XSLPP.XMLData := XMLDoc;
// XSLPP.Active := true;
Result := XSLPP.Content;
TS.Free;
XMLDoc.Free;
XSLPP.Free;
end;
正如您所看到的,我必须设置DOMVendor,而“Create(nil)”则不同。
最后的差异可能是原因,为什么?
答案 0 :(得分:1)
var
XMLDoc : IXMLDocument;
begin
XMLDoc := TXMLDocument.Create( nil );
// your code ...
XMLDoc := nil;
end;
答案 1 :(得分:1)
我找到了另一种方法,如果我无法完成上述工作,我将使用它:
导入类型库,Microsoft XML Parser,然后'使用MSXML2_TLB'并:
class function TXMLHelper.RemoveNameSpaces(XMLString: String): String;
const
// An XSLT script for removing the namespaces from any document. It will remove the prefix as well.
// From http://wiki.tei-c.org/index.php/Remove-Namespaces.xsl
cRemoveNSTransform =
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' +
'<xsl:output method="xml" indent="no"/>' +
'<xsl:template match="/|comment()|processing-instruction()">' +
' <xsl:copy>' +
' <xsl:apply-templates/>' +
' </xsl:copy>' +
'</xsl:template>' +
'<xsl:template match="*">' +
' <xsl:element name="{local-name()}">' +
' <xsl:apply-templates select="@*|node()"/>' +
' </xsl:element>' +
'</xsl:template>' +
'<xsl:template match="@*">' +
' <xsl:attribute name="{local-name()}">' +
' <xsl:value-of select="."/>' +
' </xsl:attribute>' +
'</xsl:template>' +
'</xsl:stylesheet>';
var
Doc, XSL: IXMLDOMdocument2;
begin
Doc := ComsDOMDocument.Create;
Doc.ASync := false;
XSL := ComsDOMDocument.Create;
XSL.ASync := false;
try
Doc.loadXML(XMLString);
XSL.loadXML(cRemoveNSTransform);
Result := Doc.TransFormNode(XSL);
except
on E:Exception do Result := E.Message;
end;
end; { RemoveNameSpaces }