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>
XML

Avatar of undefined
Last Comment
BigRat

8/22/2022 - Mon
BigRat

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?
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 ?
 
BigRat

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.
Your help has saved me hundreds of hours of internet surfing.
fblack61
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"  ?
BigRat

"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!!!!!
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


Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
BigRat

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.
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
BigRat

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
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Vikur

ASKER
Thank you - it's really works.
ASKER CERTIFIED SOLUTION
BigRat

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question