MSXML SAX Attributes Question
-
I am experimenting with the MSXML 3 Sax parser. When responding to the start element event I want to handle the elements attributes. I am going in circles here. The only code I can make work is to copy the entire string retuned into a CString and then trim it to the proper length. Any attemps to just access the character data only return the first character. I have tried variation of strncpy and memcpy and various casting to no effect. Any suggestions would be greatly apperciated. HRESULT STDMETHODCALLTYPE CMyContentHandler::startElement( /* [in] */ unsigned short *pwchNamespaceUri, /* [in] */ int cchNamespaceUri, /* [in] */ unsigned short *pwchLocalName, /* [in] */ int cchLocalName, /* [in] */ unsigned short *pwchRawName, /* [in] */ int cchRawName, /* [in] */ MSXML2::ISAXAttributes __RPC_FAR *pAttributes) { _bstr_t bstrString(pwchRawName); CXML *child = new CXML; CString Name,Value; Name = pwchRawName; child->SetTagName(Name); CComBSTR bstrName; int max,i,lenUri,lenLocal,lenName,lenValue,j; const wchar_t *strUri,*strLocal,*strName,*strValue; HRESULT hr; hr = pAttributes->getLength(&max); for (i=0;igetName(i,(unsigned short **)&strUri,&lenUri,(unsigned short **)&strLocal,&lenLocal,(unsigned short **)&strName,&lenName); hr = pAttributes->getValue(i,(unsigned short **)&strValue,&lenValue); Name = strName; Name = Name.Left(lenName); Value = strValue; child->SetAttr(Name,Value); } if(m_pRoot==NULL) { m_pRoot=child; } else { m_pCurrent->AddChild(child); } m_pCurrent=child; return S_OK; }
-
I am experimenting with the MSXML 3 Sax parser. When responding to the start element event I want to handle the elements attributes. I am going in circles here. The only code I can make work is to copy the entire string retuned into a CString and then trim it to the proper length. Any attemps to just access the character data only return the first character. I have tried variation of strncpy and memcpy and various casting to no effect. Any suggestions would be greatly apperciated. HRESULT STDMETHODCALLTYPE CMyContentHandler::startElement( /* [in] */ unsigned short *pwchNamespaceUri, /* [in] */ int cchNamespaceUri, /* [in] */ unsigned short *pwchLocalName, /* [in] */ int cchLocalName, /* [in] */ unsigned short *pwchRawName, /* [in] */ int cchRawName, /* [in] */ MSXML2::ISAXAttributes __RPC_FAR *pAttributes) { _bstr_t bstrString(pwchRawName); CXML *child = new CXML; CString Name,Value; Name = pwchRawName; child->SetTagName(Name); CComBSTR bstrName; int max,i,lenUri,lenLocal,lenName,lenValue,j; const wchar_t *strUri,*strLocal,*strName,*strValue; HRESULT hr; hr = pAttributes->getLength(&max); for (i=0;igetName(i,(unsigned short **)&strUri,&lenUri,(unsigned short **)&strLocal,&lenLocal,(unsigned short **)&strName,&lenName); hr = pAttributes->getValue(i,(unsigned short **)&strValue,&lenValue); Name = strName; Name = Name.Left(lenName); Value = strValue; child->SetAttr(Name,Value); } if(m_pRoot==NULL) { m_pRoot=child; } else { m_pCurrent->AddChild(child); } m_pCurrent=child; return S_OK; }
Most functions use the wchar_t datatype, which is two bytes per character. To use this data in functions which expect one byte per character you can use some MFC conversion macros. I use the following code to extract an attribute and print it:
wchar_t* val;
int valLen;pAttributes->getValueFromQName(
L"attribute", lstrlenW(L"attribute"),
&val, &valLen);USES_CONVERSION;
cout << W2T(val) << "\n";Hope this helps, Alwin Beukers
-
Most functions use the wchar_t datatype, which is two bytes per character. To use this data in functions which expect one byte per character you can use some MFC conversion macros. I use the following code to extract an attribute and print it:
wchar_t* val;
int valLen;pAttributes->getValueFromQName(
L"attribute", lstrlenW(L"attribute"),
&val, &valLen);USES_CONVERSION;
cout << W2T(val) << "\n";Hope this helps, Alwin Beukers
Alwin, Thanks very much. The W2T conversion is exactly what I was missing:) This is now working fine: int max,i,lenUri,lenLocal,lenName,lenValue; wchar_t *strUri,*strLocal,*strName,*strValue; USES_CONVERSION; HRESULT hr; hr = pAttributes->getLength(&max); for (i=0;igetName(i,&strUri,&lenUri,&strLocal,&lenLocal,&strName,&lenName); hr = pAttributes->getValue(i,&strValue,&lenValue); Name.Empty(); strncpy(Name.GetBuffer(lenName),W2T(strName),lenName); Name.ReleaseBuffer(); Value.Empty(); strncpy(Value.GetBuffer(lenValue),W2T(strValue),lenValue); Value.ReleaseBuffer(); child->SetAttr(Name,Value); }