[yunqa.de] How to perform an XML transformation in memory rather than files

  • From: "Chris Clark" <christopher.clark@xxxxxxxxxx>
  • To: <yunqa@xxxxxxxxxxxxx>
  • Date: Mon, 13 Jun 2011 12:42:41 +1200

Hi,
 
I'm trying to write a Delphi method that performs a defined XML
transformation using the DIXml_XSLT_Browser demo application as a starting
example. I want to be able to pass an XML string into the method and return
an XML string.
 
The method I've got currently is below - however the xmlReadMemory method
leaves XmlDoc as nil (so I can't see if the writing back to the string
works). It is probably my understanding of how the various pointers to the
memory positions is working. Also perhaps because it is a UnicodeString I
should be using an xmlBuffer object to package the string but unsure how to
use this.
 
I would appreciate any assistance with this please.
 
Thanks,
Chris
 
function TransformXML(const Xml: UnicodeString): UnicodeString;
var
  Buf: xmlCharPtr;
  BufSize: Integer;
  XmlDoc, XslDoc, ResultDoc: xmlDocPtr;
  XslStyle: xsltStyleSheetPtr;
  TC: xsltTransformContextPtr;
  aXml: PAnsiChar;
begin
  aXml := PAnsiChar(Xml);
  XmlDoc := xmlReadMemory(aXml, SizeOf(aXml), nil, nil, 0);
  if Assigned(XmlDoc) then
    try
      xmlXIncludeProcessFlags(XmlDoc, XSLT_PARSE_OPTIONS);
      XslDoc := xmlReadFile(PAnsiChar('http://localhost/BGTransform.xsl'),
nil, 0);
      { Convert the XML style sheet to a style structure. If this is
        successfull, the XslStyle result takes ownership off XslDoc. }
      XslStyle := xsltParseStylesheetDoc(XslDoc);
      if Assigned(XslStyle) then
        try
          { Create the transformation context. }
          TC := xsltNewTransformContext(XslStyle, XmlDoc);
          try
            xsltSetCtxtParseOptions(TC, XML_PARSE_PEDANTIC);
            { Now the actual transformation. }
            ResultDoc := xsltApplyStylesheetUser(XslStyle, XmlDoc, nil, nil,
nil, TC);
            if Assigned(ResultDoc) then
              try
                xmlDocDumpMemory (ResultDoc, @Buf, @BufSize);
                //xsltSaveResultToString (PAnsiChar(@OutBuf), ResultDoc,
XslStyle);
                Result := Buf;
              finally
                FreeMem(Buf);
                xmlFreeDoc(ResultDoc);
              end;
 
          finally
            xsltFreeTransformContext(TC);
          end;
        finally
          xsltFreeStyleSheet(XslStyle);
        end
 
      else
        begin
          xmlFreeDoc(XslDoc);
        end;
 
    finally
      xmlFreeDoc(XmlDoc);
    end;
end;

Other related posts: