BOOL CXMLElement::ParseString(LPCTSTR& strXML) { if ( ! ParseMatch( strXML, _T("<") ) ) return FALSE; if ( ! ParseIdentifier( strXML, m_sName ) ) return FALSE; while ( ! ParseMatch( strXML, _T(">") ) ) { if ( ParseMatch( strXML, _T("/") ) ) return ParseMatch( strXML, _T(">") ); if ( ! *strXML ) return FALSE; CXMLAttribute* pAttribute = new CXMLAttribute( this ); if ( ! pAttribute || ! pAttribute->ParseString( strXML ) ) { delete pAttribute; return FALSE; } CString strNameLower( pAttribute->m_sName ); strNameLower.MakeLower(); // Delete the old attribute if one exists CXMLAttribute* pExisting; if ( m_pAttributes.Lookup( strNameLower, pExisting ) ) delete pExisting; m_pAttributes.SetAt( strNameLower, pAttribute ); if ( ! m_pAttributesInsertion.Find( strNameLower ) ) m_pAttributesInsertion.AddTail( strNameLower ); // Track output order workaround } CString strClose = _T("</"); strClose += m_sName + '>'; for ( ;; ) { if ( ! *strXML ) return FALSE; LPCTSTR pszElement = _tcschr( strXML, '<' ); if ( ! pszElement || *pszElement != '<' ) return FALSE; if ( ParseMatch( strXML, _T("<![CDATA[") ) ) { pszElement = _tcsstr( strXML, _T("]]>") ); if ( ! pszElement || *pszElement != ']' ) return FALSE; if ( ! m_sValue.IsEmpty() && m_sValue.Right( 1 ) != ' ' ) m_sValue += ' '; m_sValue += Unescape( strXML, (int)( pszElement - strXML ) ); pszElement += 3; strXML = pszElement; } if ( pszElement > strXML ) { if ( ! m_sValue.IsEmpty() && m_sValue.Right( 1 ) != ' ' ) m_sValue += ' '; m_sValue += Unescape( strXML, (int)( pszElement - strXML ) ); strXML = pszElement; } if ( ParseMatch( strXML, strClose ) ) { break; } else if ( ParseMatch( strXML, _T("<!--") ) ) { pszElement = _tcsstr( strXML, _T("-->") ); if ( ! pszElement || *pszElement != '-' ) return FALSE; strXML = pszElement + 3; } else { CXMLElement* pElement = new CXMLElement( this ); if ( pElement->ParseString( strXML ) ) { m_pElements.AddTail( pElement ); } else { delete pElement; return FALSE; } } } return TRUE; }
CXMLElement* CXMLElement::FromString(LPCTSTR pszXML, BOOL bHeader, CString* pEncoding) { CXMLElement* pElement = NULL; LPCTSTR pszElement = NULL; try { if ( ParseMatch( pszXML, _T("<?xml version=\"") ) ) { pszElement = _tcsstr( pszXML, _T("?>") ); if ( ! pszElement ) return FALSE; if ( pEncoding ) { LPCTSTR pszEncoding = _tcsstr( pszXML, _T("encoding=\"") ); if ( pszEncoding && pszEncoding < pszElement ) { pszEncoding += 10; LPCTSTR pszEncodingEnd = _tcschr( pszEncoding, _T('\"') ); if ( pszEncodingEnd && pszEncodingEnd < pszElement ) pEncoding->Append( pszEncoding, pszEncodingEnd - pszEncoding ); } } pszXML = pszElement + 2; } else if ( bHeader ) return NULL; while ( ParseMatch( pszXML, _T("<!--") ) ) { pszElement = _tcsstr( pszXML, _T("-->") ); if ( ! pszElement || *pszElement != '-' ) return FALSE; pszXML = pszElement + 3; } while ( ParseMatch( pszXML, _T("<?xml") ) ) { pszElement = _tcsstr( pszXML, _T("?>") ); if ( ! pszElement ) return FALSE; pszXML = pszElement + 2; } if ( ParseMatch( pszXML, _T("<!DOCTYPE") ) ) { pszElement = _tcsstr( pszXML, _T(">") ); if ( ! pszElement ) return FALSE; pszXML = pszElement + 1; } while ( ParseMatch( pszXML, _T("<!--") ) ) { pszElement = _tcsstr( pszXML, _T("-->") ); if ( ! pszElement || *pszElement != '-' ) return FALSE; pszXML = pszElement + 3; } pElement = new CXMLElement(); if ( ! pElement->ParseString( pszXML ) ) { delete pElement; pElement = NULL; } } catch ( CException* pException ) { pException->Delete(); delete pElement; pElement = NULL; } return pElement; }