Hi,

I'm having great difficulty getting my transform function to work.

I have some XML in a string buffer, an XSLT file and need to send HTML
output to another string buffer.

I've tried using streams but I get a segmentation fault. Strangely the same
occurs if I specify the XML and output HTML as files (having sent the XML
buffer to a file). e.g. by doing... xslTransformer.transform("my.xml",
"Transforms/my.xsl", "my.html").

If I run the same transform through the command line XalanTransformer,
however, it works! e.g. bash$ XalanTransformer("my.xml",
"Transforms/my.xsl", "my.html")

It should be noted that I'm running this through Perl using SWIG wrappers
(www.swig.org) to interface with my code which is in a C++ library, however
I've run it through a simple C++ test app (no Perl or SWIG) and it still
doesn't work, although it doesn't crash (the transform just fails) - at
least it doesn't using the streams. It works with the explicit filenames
(but only when I use a C++ test app, not through Perl). Saving out to files
and running the transform isn't the ideal solution though. The only file
used should be the XSL, and even then I may store that in memory as a
compiled stylesheet (I've tried that as well and it makes no difference).

Below is the code doing the job. I get the segmentation fault in
xslTransformer.transform().
I've tried istringstream as well as istrstream.

strXmlIn and strHtmlOutBuf are std::string types.

                XMLPlatformUtils::Initialize();
                XalanTransformer::initialize();

                XalanTransformer xslTransformer;

                istrstream xmlInStream(strXmlIn.c_str(), strXmlIn.length());
                ostringstream htmlOutStream(strHtmlOutBuf);

                XSLTInputSource xmlIn(&xmlInStream);
                XSLTInputSource xslIn(strXSLTPath.c_str());
                XSLTResultTarget htmlOut(&htmlOutStream);
                
                const XalanDOMString xmlSystemID("XML Stream input");
                xmlIn.setSystemId(c_wstr(xmlSystemID));
                
//              const XalanDOMString xslSystemID("XSL file input");
//              xslIn.setSystemId(c_wstr(xslSystemID));
                
                try
                {
                        if (xslTransformer.transform(xmlIn, xslIn, htmlOut)
!= 0)
                                cout << "Error in transform: " <<
xslTransformer.getLastError() << endl;
                }
                catch(XSLException& eException)
                {
                        cout << "Exception in transform: " <<
eException.getMessage();                
                }

                XalanTransformer::terminate();

                XMLPlatformUtils::Terminate();


The following is the stack when it crashes...

XalanTransformer::transform(0xffbeee00, 0xffbeeb8c, 0xffbeeb70, 0xffbeeb30,
0x11ca30, 0x7ffffc00)
XalanTransformer::transform(0x1a, 0xffbee6c4, 0xffbee6dc, 0xffbee888,
0xffbee9a8, 0xffbee618)
XSLTEngineImpl::process(0xffbee6dc, 0xffbee618, 0xffbeeb70, 0xffbee640,
0xffbee680, 0x12c810)
StylesheetRoot::process(0x19e408, 0x21fc, 0xffbee640, 0x12c810, 0x54,
0xfed45024)
StylesheetRoot::setupFormatterListener(0x19e408, 0x0, 0x12c810, 0x1, 0x2,
0xfed6ab40)
StylesheetExecutionContextDefault::createFormatterToHTML(0x12c810, 0x1e6c64,
0x19e710, 0x19e724, 0x19e738, 0x19e74c)
FormatterToHTML::FormatterToHTML(0x1b9008, 0x1, 0x19e764, 0x1, 0x2, 0x2400)
FormatterToXML::FormatterToXML(0x1b9008, 0x0, 0x1b9500, 0x1b94ec,
0xfed642e4, 0x1b94d8)
XalanTranscodingServices::getMaximumCharacterValue(0x1b9450, 0x1b9450,
0x158428, 0x0, 0x0, 0x0)
TransformString(0xffbedf54, 0x1e6970, 0x5, 0xfebe096c, 0x22f4, 0xfed45024)
XalanDOMString::XalanDOMString(0xffbedf54, 0xffbedecc, 0x0, 0xffffffff,
0xfebe096c, 0xfead9f0b)
XalanDOMString::append(0xffbedf54, 0x190eb0, 0xffffffff, 0xffffffff,
0xfebe096c, 0xfeaaff5a)
std::vector >::__insert_aux2(0xffbedf54, 0xfef673f0, 0x190eb0, 0x190eba,
0x190eb0, 0x1fc23c)
std::uninitialized_copy(0x190eb2, 0x190eba, 0xfef673f2, 0x0, 0x0, 0x0)


Note that if I uncomment these lines...

//              const XalanDOMString xslSystemID("XSL file input");
//              xslIn.setSystemId(c_wstr(xslSystemID));

... It doesn't crash. However it says something about not finding the base
pathname and just doesn't succeed. i.e.:

"Error in transform: XSLT warning: Fatal Error at (file , line 0, column 0):
An exception occured! Type:XMLPlatformException, Message:Could not determine
base pathname of the file (, line -1, column -1)"

I assume this is because setting the system ID only applies to streams,
whereas I'm specifying a filename for the XSLT file? However, this is the
same error I get with the plain C++ app that doesn't crash (and has the
above lines commented out).

I can't post the full XML/XSLT files as they're company confidential, but as
I say they work fine with the command line XalanTransformer. The encoding
they use is UTF-8. However, the following are the headers from each...

XML: <?xml version="1.0" encoding="utf-8"?>
XSLT: <?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">


For info (and maybe throwing a spanner or two into the works), all of this
is within a project that links to Oracle libraries, builds in SWIG wrappers
for Perl, and built as a shared library which is called from Perl.

I'm using the pre-built libraries for Xalan & Xerces, (specifically this
one: http://xml.apache.org/dist/xalan-c/Xalan-C_1_3-solaris.tar.gz - and
yes, I'm using GNU Tar to unzip).

I'm building with the Sun Workshop 6 (update 1) C++ compiler (5.2 Patch
109508-06 2001/11/07), and the environment is as follows...

SunOS sun250 5.8 Generic_108528-12 sun4u sparc SUNW, Ultra-250.

Perl version is 5.6.1 (built using the Sun compiler), and SWIG is
1.3.11u-20020211-1543.

Oh, and compile options are roughly as follows...

For compiling (there are lots of source files really, but only one deals
with the xml bit)...
CC -c -g mysource.cpp

For linking...
CC -G $(OBJ_FILES) -L$(LIBHOME) -L$(RDBMSLIB) -L/usr/local/lib
-lxerces-c1_6_0 -lxalan-c1_3 $(OCICCCSHAREDLIBS) -L/opt/SUNWspro/lib -lCrun
-lCstd -o libMyLibrary.so

LIBHOME, RDBMSLIB and OCICCCSHAREDLIBS are to do with Oracle.

For some reason I have to do the -lCrun and -lCstd with the library path
before it and in that order else I get major run-time link problems in perl.

I understand that the segmentation fault could be an issue with perl/swig,
but still it doesn't work anyway without perl/swig in the equation (not
using streams at least).

I'd try GNU C++ but I can't get that to work properly (probably because the
Xalan/Xerces libraries are built with the Sun Workshop compiler. I've tried
building the libraries with GNU C++ but can't get them to build on Solaris
using GNU).


Any ideas?


Regards,

Tim.

Reply via email to