Solved

Appending a IXMLDOMElement to a IXMLDOMNode

Posted on 2002-03-21
19
1,080 Views
Last Modified: 2007-11-27
In my HTML page, I have a data island containing a list of customers which are diplayed on screen. When the user clicks on a button, I use a MSXML2.XMLHTTP.3.0 object in a VBScript to connect to an ASP page, which connects to our SQL database, calls a stored procedure and returns all known addresses for the currently selected employee. All this works fine.

I would like to add the addresses to the data island so that I don't need to make another round trip if the user selects the same customer during his session but when I call the appendChild method, I get the following error message: "The parameter is incorrect".

Here is my VBScript code:
Dim objXMLHTTP
Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP.3.0")
objXMLHTTP.open "POST", "xt_GetDomainData.asp?CustomerId=" & nCustomerId & "&Data=Addresses", False
objXMLHTTP.send ""

Set objAddresses = objXMLHTTP.responseXML.documentElement.selectSingleNode("//Addresses")

' xmlData is the data island
Set objCustomerNode = xmlData.XMLDocument.selectSingleNode("/Customers/Customer[CustomerId='" & nCustomerId & "']")

' This is for debugging purposes
MsgBox "From XMLHTTP: " & TypeName(objAddresses) & vbCrLf & "From Data Island: " & TypeName(objCustomerNode)

' This line fails
Call objCustomerNode.appendChild(objAddresses)

If I display the type name of objAddresses I see that it's a IXMLDOMElement while objCustomerNode is a IXMLDOMNode and I'm guessing that the fact the two are not the same type is causing this problem.

My question is: is there a way to "cast" objAddresses into an object type that can be appended to the data island?

0
Comment
Question by:FrenchJericho
  • 14
  • 5
19 Comments
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
Sample Code To Illustrate Point
===============================
<html>
<head>
<title>Data Island</title>
<script>
var oXML3 = new ActiveXObject("Msxml2.DOMDocument.3.0");
var oXML4 = new ActiveXObject("Msxml2.DOMDocument.4.0");
oXML3.async = oXML4.async = false;
oXML3.loadXML("<payload id='3'><customers>10</customers></payload>");
oXML4.loadXML("<payload id='4'><customers>10</customers></payload>");
window.onload = init;

function init() {
     oDOM = data.XMLDocument;
     oRoot = oDOM.documentElement;
     alert(oRoot.xml);
     var oNew = oDOM.createElement("users")
     oNew.setAttribute("id","1234");
     oNew.text = 20;
     oRoot.appendChild(oNew);
     alert(oRoot.xml);
     var oParent = oDOM.selectSingleNode("//container");
     try {
          oParent.appendChild(oXML3.documentElement);
     } catch (e1) {
          alert(e1.description);
     }
     alert(oRoot.xml);
     try {
          oParent.appendChild(oXML4.documentElement);
     } catch (e2) {
          alert(e2.description);
     }
     alert(oRoot.xml);
}
</script>
</head>
<body>
<xml id="data">
<payload>
     <users>10</users>
     <container />
</payload>
</xml>
</body>
</html>
0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
The issue is not of casting, it is a probably a problem with the Parser that is instantiated via the XML Data Island being of a different version than the Parser used via the scripted code.
0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
Currently, the latest version that can be instantiated within an XML Data Island is MSXML3. By default, unless you have installed MSXML3 SP2 or MSIE 6.x, the default Parser for MSIE is NOT MSXML3 and thus, you must download the xmlinst from msdn.microsoft.com/xml --> MSXML3 Link. and run it without any parameters to ensure that the default Parser is Version 3.0 and Not 2.x.

Next, I must question your design decision, if you have scripted code instantiating Msxml2.XMLHTTP.3.0, what are you really doing with data islands, use scripted code to get what you want done.
0
 

Author Comment

by:FrenchJericho
Comment Utility
I'm using the data island so I can bind a table to it and diplay one row per customer without much effort
0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
then, you would have to run the xmlinst on EVERY CLIENT to ensure that the default XML Parser for MSIE is MSXML3.

The other alternative is to write brute code, looping thru the node structure, attributes, child elements and text node and append them gradually to the xml data island...good luck there!
0
 

Author Comment

by:FrenchJericho
Comment Utility
Is there an "older" version of the XMLHTTTP that would be compatible with the default parser on the client?
0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
The sample code, shows that when the parser via code and the parser via the XML Data Islands are the same, you can use the appendChild method without much ado.

Of course, I have MSXML3 SP2 and this means that it is installed in replace mode, the XML Data Islands use the MSXML3 SP2 Parser since this is the default MSXML Parser For MSIE
0
 

Author Comment

by:FrenchJericho
Comment Utility
My problem is that I can't assume that all the clients will have MSXML in replace mode. Is there a progId for XMLHTTP that will instanciate the same parser that is used by IE?
0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
yes,

Dim objXMLHTTP
Set objXMLHTTP = CreateObject("Microsoft.XMLHTTP")

But there are so many versions of the old 2.x that there is virtually no guarantee that the appendChild will work unfortunately.

More over, if someone had the ability to run xmlinst on their box and make MSXML3 the default parser or install MSIE 6 which makes MSXML3 SP2 the default parser, you are back to square one.

Only when the versions are the same, will the appendChild work.

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
>>
My problem is that I can't assume that all the clients will have MSXML in replace mode. Is there a progId
for XMLHTTP that will instanciate the same parser that is used by IE?
<<

a biiiig NOOOOOOOOOOOOOOOO....
0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
For clarification
=================

>>
yes,

Dim objXMLHTTP
Set objXMLHTTP = CreateObject("Microsoft.XMLHTTP")

But there are so many versions of the old 2.x that there is virtually no guarantee that the appendChild
will work unfortunately.

More over, if someone had the ability to run xmlinst on their box and make MSXML3 the default parser
or install MSIE 6 which makes MSXML3 SP2 the default parser, you are back to square one.

Only when the versions are the same, will the appendChild work.
<<
was in response to your question of
"Is there an "older" version of the XMLHTTTP that would be compatible with the default parser on the
client? "
0
 

Author Comment

by:FrenchJericho
Comment Utility
In that case, is there a way to figure out the version of the default parser and use the appropriate progId?
0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
For that reason and many other reasons, I strongly discourage using Data Islands. Microsoft has abandoned the replace mode for MSXML4. MS has realised that the replace mode makes things very complicated for developers as you are now discovering.

This means that Data Islands and xml documents loaded directly via MSIE cannot and do not use MSXML4.

0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
There is code to figure the version, but that is an approximation when it comes to the older versions =)
0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
i will post that code to you after my smoke break <GRIN>
0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
it will make use of the Data Island to figure out the progid
0
 

Author Comment

by:FrenchJericho
Comment Utility
This is getting more complicated than I tought it would!!!!!

I tought I was asking a simple question and that my problem could be solved with a few lines of code :-(
0
 
LVL 23

Accepted Solution

by:
b1xml2 earned 200 total points
Comment Utility
1. add another data island to the html page
<xml id="parserCheck">
<payload />
</xml>

2.
add this code.
vbscript
========
Function HTTPProgId()
On Error Resume Next
Dim oCheck, oRoot
HTTPProgId = "Microsoft.XMLHTTP"
Set oCheck = CreateObject("Msxml2.DOMDocument.3.0")
If Err Then Exit Function
oCheck.async = False
oCheck.loadXML "<check />"
Set oRoot = document.all.parserCheck.XMLDocument.documentElement
oRoot.appendChild oCheck.documentElement
If Err Then Exit Function
If oRoot.hasChildNodes Then HTTPProgId = "Msxml2.XMLHTTP.3.0"
End Function


3. instantiate this code AFTER the window has been loaded
MSIE5+
=====
Dim szProgId
Set Window.OnLoad = GetRef("init")

Function Init()
szProgId = HTTPProgId()
End Function


4. Use the global variable accordingly,
Dim objXMLHTTP
Set objXMLHTTP = CreateObject(szProgId)

0
 
LVL 23

Expert Comment

by:b1xml2
Comment Utility
btw, you will get the error message, "the parameter is incorrect" when the parsers are not the same version. Talk about intelligent error messages ROFL!
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now