1

我正在根据Bob Swart 的“Delphi XE2 XML, SOAP & Web Services Development”一书中的文档对 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)”是不同的。
最后的差异可能是原因吗?为什么?

4

2 回答 2

1

将其用作TXMLDocument 用例中所述的接口

var
  XMLDoc : IXMLDocument;
begin
  XMLDoc := TXMLDocument.Create( nil );

  // your code ...

  XMLDoc := nil;
end;
于 2012-11-21T16:44:44.557 回答
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 }
于 2012-11-22T09:05:20.020 回答