Hi, I am new to using the MSXML functions in C++. I found this on MSDN as
an example of what I wanted to do,
http://msdn2.microsoft.com/en-us/library/ms765465.aspx.
I have tried a number of XPATH examples to try and retrieve the
"><Code>12455</Code>", but have been unable to do so. The MSDN example works
fine. So, I am wondering if it's a namespace issue?
Any help would be appreciated. Thanks. Jeff
I have changed the code as follows:
int _tmain(int argc, _TCHAR* argv[])
{
CString sResponse = "<?xml version=\"1.0\" encoding=\"utf-8\" ?> <string
xmlns=\"http://tempuri.org/\"><InquiryResponse><Code>12455</Code></InquiryResponse></string>";
//CString sResponse = "<?xml version=\"1.0\"?><?xml:stylesheet
type=\"text/xsl\" href=\"stock.xsl\"?><portfolio
xmlns:dt=\"urn:schemas-microsoft-com:datatypes\"> <stock
exchange=\"nasdaq\"> <name>new</name> <symbol>zzzz</symbol> <price
dt:dt=\"number\">20.313</price> </stock> <stock exchange=\"nyse\">
<name>zacx corp</name> <symbol>ZCXM</symbol> <price
dt:dt=\"number\">28.875</price> </stock> <stock exchange=\"nasdaq\">
<name>zaffymat inc</name> <symbol>ZFFX</symbol> <price
dt:dt=\"number\">92.250</price> </stock> <stock exchange=\"nasdaq\">
<name>zysmergy inc</name> <symbol>ZYSZ</symbol> <price
dt:dt=\"number\">20.313</price> </stock></portfolio>";
BSTR bstr = sResponse.AllocSysString();
BSTR bstr2 = '\0';
IXMLDOMDocument *pXMLDom=NULL;
IXMLDOMParseError *pXMLErr=NULL;
IXMLDOMNode *pNode=NULL;
VARIANT_BOOL status;
VARIANT var;
HRESULT hr;
CoInitialize(NULL);
pXMLDom = DomFromCOM();
if (!pXMLDom)
goto clean;
// Load the XML string into the DOM Object
HRCALL(pXMLDom->loadXML(bstr, &status), "");
if (status!=VARIANT_TRUE)
{
HRCALL(pXMLDom->get_parseError(&pXMLErr),"");
HRCALL(pXMLErr->get_reason(&bstr),"");
dprintf("Failed to load DOM from string. %S\n",
bstr);
goto clean;
}
HRCALL(pXMLDom->get_xml(&bstr2), "");
dprintf("XML DOM loaded from string:\n%S\n",bstr2);
Sleep(3000);
// Query a single node.
if (bstr2)
SysFreeString(bstr2);
bstr2 = SysAllocString(L"//InquiryResponse/Code/*"); // Nothing
//bstr2 = SysAllocString(L"//InquiryResponse/*"); //Nothing
//bstr2 = SysAllocString(L"//*"); // Works
//bstr2 = SysAllocString(L"//string/InquiryResponse/Code"); // Nothing
//bstr2 = SysAllocString(L"//*"); // Too much info
HRCALL(pXMLDom->selectSingleNode(bstr2, &pNode), "dom->selectSingleNode:
");
if (!pNode)
{
ReportParseError(pXMLDom, "Calling selectSingleNode ");
}
else
{
dprintf("Result from selectSingleNode:\n");
if (bstr2)
SysFreeString(bstr2);
HRCALL(pNode->get_nodeName(&bstr2)," get_nodeName ");
dprintf("Node, <%S>:\n", bstr2);
if (bstr)
SysFreeString(bstr2);
HRCALL(pNode->get_xml(&bstr2), "get_xml: ");
dprintf("\t%S\n\n", bstr2);
Sleep(15000);
}
clean:
if (bstr) SysFreeString(bstr);
if (&var) VariantClear(&var);
if (pXMLErr) pXMLErr->Release();
if (pXMLDom) pXMLDom->Release();
CoUninitialize();
return 0;
}
Martin Honnen - 13 Mar 2007 18:25 GMT
> CString sResponse = "<?xml version=\"1.0\" encoding=\"utf-8\" ?> <string
> xmlns=\"http://tempuri.org/\"><InquiryResponse><Code>12455</Code></InquiryResponse></string>";
The elements are in the default namespace so with MSXML you need e.g.
(JScript syntax, translate to C++ as needed)
xmlDocument.setProperty('SelectionNamespaces',
'xmlns:pf="http://tempuri.org/"');
xmlDocument.selectNodes('pf:string/pf:InquiryResponse')

Signature
Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
j.a. harriman - 21 Mar 2007 18:27 GMT
Thanks for pointing me in the right direction.
I've been meaning to update this for others who come along. Or in case I
forget!
The "IXMLDOMDocument" (in my original post) had to be a "IXMLDOMDocument2"
to access the "setProperty" function that the "IXMLDOMDocument" doesn't have.
And also had to add the following:
CString s = "SelectionNamespaces";
BSTR name = s.AllocSysString();
BSTR x = SysAllocString(L"xmlns:pf=\"http://tempuri.org/\"");
VARIANT myVariant;
myVariant.vt = VT_BSTR;
myVariant.bstrVal = x;
so, here was the call:
hr = pXMLDom->setProperty(name, myVariant);
// Release values
if (x) SysFreeString(x);
if (name) SysFreeString(name);
if (&myVariant) VariantClear(&myVariant);
I also recommend downloading the sample "VariantUse"
http://msdn2.microsoft.com/en-us/library/ms177538(VS.80).aspx
that proved invaluable for me.
Jeff
> > CString sResponse = "<?xml version=\"1.0\" encoding=\"utf-8\" ?> <string
> > xmlns=\"http://tempuri.org/\"><InquiryResponse><Code>12455</Code></InquiryResponse></string>";
[quoted text clipped - 4 lines]
> 'xmlns:pf="http://tempuri.org/"');
> xmlDocument.selectNodes('pf:string/pf:InquiryResponse')
Bjoern Hoehrmann - 13 Mar 2007 18:27 GMT
* j.a. harriman wrote in microsoft.public.dotnet.xml:
>I have tried a number of XPATH examples to try and retrieve the
>"><Code>12455</Code>", but have been unable to do so. The MSDN example works
>fine. So, I am wondering if it's a namespace issue?
It is. You have to declare prefixes for the namespaces you are using and
use them in your expressions as appropriate. For example, you could de-
clare "tmp" = ""http://tempuri.org/" and then use /tmp:string in your
example. The MSDN documentation for selectNodes has a C++ example for
how to declare namespace prefixes.

Signature
Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/