Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help - how to preserve XML Structure using C++ XSL Transform?

1 view
Skip to first unread message

Nanker

unread,
Nov 20, 2007, 6:13:09 PM11/20/07
to
I have the following XML:

<PrivateXML App="MyApp">
<Version version_no="1.0.0.0" version_date="Monday, March 26,
2007"/>
<PrivateDevices>
<PrivateDevice DeviceID="1" Model="">
<Speaker SpeakerID="0" name="MySpeaker"/>
</PrivateDevice>
</PrivateDevices>
</PrivateXML>

and the following XSL:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:output media-type="text/xml" method="xml" encoding="utf-8"
indent="yes"/>

<!-- Identity Transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<!-- Find the Version element and add the theName attribute -->
<xsl:template match="Version">
<xsl:copy>
<xsl:attribute name="theName">MyName</xsl:attribute>
<xsl:apply-templates select="@*|*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Using this pair with some C# transform applications, my results are
the following (which is what I'm looking for):

<PrivateXML App="MyApp">
<Version theName="MyName" version_no="1.0.0.0"
version_date="Monday, March 26, 2007" />
<PrivateDevices>
<PrivateDevice DeviceID="1" Model="">
<Speaker SpeakerID="0" name="MySpeaker" />
</PrivateDevice>
</PrivateDevices>
</PrivateXML>

Using the following Visual C++ method:

bool PerformXslTransform(_bstr_t xmlSource, const bool
isSourceAFile,
IXSLProcessorPtr pProcessor, _bstr_t* transformedResult)
{
// Initialize all local variables
void *output = NULL;
XML2DocumentPtr pXml = NULL;
IStream *pOutStream;
bool success=false;

// load source XML and the XSL file
try
{
// Load the XML differently whether specified as a file or raw
XML
if(isSourceAFile)
{
pXml = pdocCreateFromUrl(xmlSource);
}
else
{
pXml = pdocCreateFromString(xmlSource);
}

// prepare Stream object to store results of transformation
CreateStreamOnHGlobal(NULL,TRUE,&pOutStream);
pProcessor->put_output(_variant_t(pOutStream));

// Attach to processor XML to transform, and do the
transoformation
pProcessor->put_input(_variant_t((IUnknown*)pXml));
pProcessor->transform();

//Get results of transformation
HGLOBAL hg = NULL;
pOutStream->Write((void const*)"\0",1,0);
GetHGlobalFromStream(pOutStream,&hg);
output = GlobalLock(hg);
*transformedResult = (const char*)output;
GlobalUnlock(hg);

success = true;
}
catch(...)
{
}

//release these components
if(pXml != NULL)
{
pXml.Release();
}

return success;
}

My results are instead the following:

<PrivateXML App="MyApp">
<Version theName="MyName" version_no="1.0.0.0"
version_date="Monday, March 26, 2007">
</Version>
<PrivateDevices>
<PrivateDevice DeviceID="1" Model="">
<Speaker SpeakerID="0" name="MySpeaker">
</Speaker>
</PrivateDevice>
</PrivateDevices>
</PrivateXML>

I realize that these are equivalent, but these files in my environment
will possibly end up being edited by support teams, and I would rather
preserve the format:

<Speaker SpeakerID="0" name="MySpeaker"/>

instead of changing it to:

<Speaker SpeakerID="0" name="MySpeaker">
</Speaker>

Since the XSL provides the desired results using C#, I'm hoping that
there is something I'm missing with my C++ code to preserve the
element structure.

Can someone please provide some guidance as to how I can preserve this
structure using C++?

Thanks in advance

Joe Fawcett

unread,
Nov 21, 2007, 5:43:41 AM11/21/07
to
"Nanker" <nan...@sacbeemail.com> wrote in message
news:954d338f-8a82-4099...@e10g2000prf.googlegroups.com...
Possibly setting to preserveWhitespace to true/false explicitly on the
document instance would help.

--

Joe Fawcett (MVP - XML)

http://joe.fawcett.name


Nanker

unread,
Nov 21, 2007, 10:08:15 AM11/21/07
to
Thanks for the response - I tried that as well, but it provided the
same results.

Martin Honnen

unread,
Nov 21, 2007, 10:15:17 AM11/21/07
to
Nanker wrote:
> Thanks for the response - I tried that as well, but it provided the
> same results.

use preserveWhiteSpace = true before you load the XML input, then take
out the <xsl:output indent="true"/> that you have in your stylesheet
respectively use <xsl:output indent="false"/>.


--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/

0 new messages