?
Solved

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

Posted on 2003-02-22
11
Medium Priority
?
1,576 Views
Last Modified: 2007-12-19
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>
0
Comment
Question by:Vikur
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
11 Comments
 
LVL 27

Expert Comment

by:BigRat
ID: 8017111
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?
0
 

Author Comment

by:Vikur
ID: 8017823

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 ?
 
0
 
LVL 27

Expert Comment

by:BigRat
ID: 8024893
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.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:Vikur
ID: 8025804
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"  ?
0
 
LVL 27

Expert Comment

by:BigRat
ID: 8027032
"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!!!!!
0
 

Author Comment

by:Vikur
ID: 8027214
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


0
 
LVL 27

Expert Comment

by:BigRat
ID: 8032938
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.
0
 

Author Comment

by:Vikur
ID: 8033500
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
0
 
LVL 27

Expert Comment

by:BigRat
ID: 8033565
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
0
 

Author Comment

by:Vikur
ID: 8033803
Thank you - it's really works.
0
 
LVL 27

Accepted Solution

by:
BigRat earned 400 total points
ID: 8033889
So you've got it working!

Cheese, by any chance?
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question