Link to home
Start Free TrialLog in
Avatar of Vikur
Vikur

asked on

TransformNode() MSXML using C++ doesn't work

Hi,
A following code retutn exeption on loadXML function. What is wrong ?


#include <windows.h>
#import  <msxml3.dll>

typedef MSXML2::IXMLDOMDocumentPtr     DocPtr;
typedef MSXML2::IXMLDOMNodePtr            NodePtr;

void get_error(DocPtr doc)
{
      MSXML2::IXMLDOMParseErrorPtr  pErr = doc->GetparseError();//parseError;  
       if( pErr->GeterrorCode() != 0)
          throw pErr->Getreason();
       else
          AfxMessageBox ("loaded successfuly");
}

///////////////////////////////////////
void tform(char* c_args)
{
     CoInitialize(NULL);
   try
   {      
       DocPtr xmlDoc(__uuidof(MSXML2::DOMDocument));
//This loads the text that I want to transform
       xmlDoc->load(c_args);      
       get_error(xmlDoc);
//This loads the XSLT transform
       DocPtr xslDoc(__uuidof(MSXML2::DOMDocument));
          xslDoc->load("sam1.xsl");
       get_error(xmlDoc);
//This transforms

     DocPtr xmlDso(__uuidof(MSXML2::DOMDocument));

     NodePtr xmlroot = xmlDoc->GetdocumentElement();
     NodePtr xslroot = xslDoc->GetdocumentElement();
     _bstr_t str = xmlroot->transformNode(xslroot) ;
// THERE IS FAULT OCCURE
 xmlDso->loadXML(str);
     get_error(xmlDso);
     xmlDso->save("newFile.xml");

   }
   catch(char* lpstrErr) {
          // Some error...
          AfxMessageBox(lpstrErr );
   }      catch(...) {
          // Unknown error...
          AfxMessageBox("Unknown error..." );
     }

   CoUninitialize();
}

/////////////////////////////////////

<?xml version="1.0" encoding="UTF-8"?>

<source>
<title>XSL</title>
<author>John Smith</author>
</source>

/////////////////////////////////////////////

<xsl:stylesheet version = '1.0'
     xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>

<xsl:template match="/">
     <h1>
          <xsl:value-of select="//title"/>
     </h1>
     <h2>
          <xsl:value-of select="//author"/>
     </h2>
</xsl:template>

</xsl:stylesheet>
Avatar of BigRat
BigRat
Flag of France image

I would suspect that "bstr_t str = xmlroot->transformNode(xslroot);" has not produced a well-formed XML string. Try adding a box to output it before loading. Futhermore what did the ParseError object return for reason code and column position?
Avatar of Vikur
Vikur

ASKER


You absolutely right:  transformNode return a following string
""<?xml version="1.0" encoding="UTF-8"?XSLJohnSmith 1"

So , it erases all tag names from XML and nothing else - without any error. Why ? may be somthing wrong on XSLT ?
 
Now that is a VERY strange string"! The back > is missing.

You do have another error. After creating the DOM objects you MUST set the property async to false, otherwise the object creates a thread and executes the loading in background. Your thread is still running and the other threads have not yet started so there is no error object and consequently the transform could go wrong. Put that in first.
Avatar of Vikur

ASKER

Sorry,my error
returned a following string :
"<?xml version="1.0" encoding="UTF-16"?> XSL John Smith(1)"

What are you think
why
encoding="UTF-16" instead of  encoding="UTF-8"  ?
"What are you think"

The encoding is correct, since you have a BSTR which is a w_char type ie: 16 bit characters. The official type for this is actually UTF-16.

You MUST set the async property to false!!!!!
Avatar of Vikur

ASKER

Thanks and sorry for mistake. Anyway ...

     I have corrected it and it doesn't help ( puting async to false). Seems, somthing wrong with encoding :

Input first string : <?xml version="1.0" encoding="UTF-8"?>

Output ( as mentioned ) : "<?xml version="1.0" encoding="UTF-16"?> XSL John Smith(1)"


   So , first of all, it change encoding ( When I change it to UTF-16 it fails on xmlDoc->load . I check it now )

   On the other hand it transforms body  wrongly : I expect to recieve on output somthing like

.............
<h1>
         XSL
</h1>
<h2>
         John Smith
</h2>

and not  

XSL John Smith(1)

   Or it shoud be so - without tag names ?

Thanks


First of all the UTF-16 encoding is correct. Don't change anything.

Second the transform function has included a correct XML header but has not output any XML text - just RAW text. Can you post your transform XSL here? I suspect that the <xsl:output method="...."/> is incorrect. The DEFAULT is actually HTML but if it is incorrectly specified the transformer "guesses" and it looks as if it has guessed "text" but added a header.
Avatar of Vikur

ASKER

My XSL
After correction ( added <xsl:output method="HTML"/> ) :

<xsl:stylesheet version = '1.0'
    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method="HTML"/>

<xsl:template match="/">
    <h1>
         <xsl:value-of select="//title"/>
    </h1>
    <h2>
         <xsl:value-of select="//author"/>
    </h2>
</xsl:template>
</xsl:stylesheet>

And now my output : "XSLJohn Smith" - without header line .
I goiwng to try to use TransformNodeToObject instead ,as recommended on MSDN.

Thanks a lot
So you had no <xsl:output/> tag?

In which case to get XML output the tag should read :-

<xsl:output method="xml" omit-xml-declaration="no"  standalone="yes"/>

which will give you :-

<?xml version="1.0" standalone="yes" encoding="utf-16"?>
<h1>title</h1><h2>author</h2>

better would be :-


<xsl:template match="/">
  <h>
   <h1>
        <xsl:value-of select="//title"/>
   </h1>
   <h2>
        <xsl:value-of select="//author"/>
   </h2>
  </h>
</xsl:template>

which gives you a single root node, you can then repeat the other tags inside it.

HTH
Avatar of Vikur

ASKER

Thank you - it's really works.
ASKER CERTIFIED SOLUTION
Avatar of BigRat
BigRat
Flag of France image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial