|
I found further down some help with this. Now have these warnings:
<pre lang="text">1>XMLite.cpp(295): warning C4244: 'initializing': conversion from '__int64' to 'int', possible loss of data
1>XMLite.cpp(1792): warning C4244: 'return': conversion from '__int64' to 'int', possible loss of data
1>XMLite.cpp(1817): warning C4244: 'return': conversion from '__int64' to 'int', possible loss of data
1>XMLite.cpp(1825): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
1>XMLite.cpp(1841): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
</pre>
|
|
|
|
|
Hello,
Why using the CPOL license ? This license is not a free software license and has several restrictions :
https://www.gnu.org/licenses/license-list.en.html
"You agree not to use the Work for illegal, immoral or improper purposes, or on pages containing illegal, immoral or improper material."
"You agree not to sell, lease, or rent any part of the Work."
You should use a GNU GPL license or Apache license or another free software license instead.
|
|
|
|
|
I finally had time to get the xml output properly formatted.
I had a save and a load function and was constantly re-parsing the saved xml. Discovered that linebreaks were accumulated after each end tag. There were also two ugly empty lines at the start of the document. Try the following changes to _tagXMLNode::GetXML for a prettier output:
AFX_EXT_API CString _tagXMLNode::GetXML( LPDISP_OPT opt )
{
std::ostringstream os;
if( type != XNODE_DOC && type != XNODE_PI && opt && opt->newline )
{
...
...
if( value != _T("") )
{
if( opt && opt->newline && !childs.empty() )
{
int i;
}
os << (LPCTSTR)(opt->reference_value&&opt->entitys?opt->entitys->Entity2Ref(value):value);
}
if( opt && opt->newline && !childs.empty() )
{
int i;
}
os << "</" << (LPCTSTR)name << '>';
...
...
}
Here are my save and load functions for completeness:
AFX_EXT_API LPTSTR _tagXMLDocument::LoadFile( LPCTSTR pszFilename, LPPARSEINFO pi )
{
CFile xmlf;
LPTSTR lptstrRet = NULL;
if (xmlf.Open(pszFilename, CFile::modeRead))
{
DWORD l = (DWORD)xmlf.GetLength();
char *xmlbuffer = new char[l+1];
xmlbuffer[l] = '\0';
TRY
{
xmlf.Read(xmlbuffer, l);
lptstrRet = Load(xmlbuffer, pi);
}
CATCH(CFileException, e)
{
CString csErr = "Error reading '" + pszFilename + "'";
AfxMessageBox(csErr , MB_ICONSTOP);
}
END_CATCH
xmlf.Close();
delete xmlbuffer;
}
return lptstrRet;
}
AFX_EXT_API BOOL _tagXMLDocument::SaveFile(LPCTSTR pszFilename, LPDISP_OPT opt )
{
CFile xmlf;
if (xmlf.Open(pszFilename, CFile::modeWrite|CFile::modeCreate))
{
TRY
{
CString csXML = GetXML(opt);
xmlf.Write(csXML, csXML.GetLength());
}
CATCH(CFileException, e)
{
CString csErr = "Error saving '" + pszFilename + "'";
AfxMessageBox(csErr , MB_ICONSTOP);
xmlf.Close();
return FALSE;
}
END_CATCH
xmlf.Close();
return TRUE;
}
return FALSE;
}
Edit: Another small bug... Change
pi->error_string.Format(_T("%s must be closed with </%s>"), name );
to
pi->error_string.Format(_T("%s must be closed with </%s>"), name, name );
modified 17-Jun-14 16:03pm.
|
|
|
|
|
I am study some kind of XML learning, and try to make a XML parsing program.
It is helpful . Good Job!
|
|
|
|
|
Great job on software.
Have you ever attempted to compile with Vusal Studio 2008? I am running into errors with _c:\temp\xmlite_demo\xmlite.cpp(1425) : error C2664: 'std::_Vector_iterator<_Ty,_Alloc>::_Vector_iterator(const std::_Vector_iterator<_Ty,_Alloc> &)' : cannot convert parameter 1 from 'int' to 'const std::_Vector_iterator<_Ty,_Alloc> &'
1> with
1> [
1> _Ty=LPXNode ,
1> _Alloc=std::allocator<LPXNode >
1> ]
1> Reason: cannot convert from 'int' to 'const std::_Vector_iterator<_Ty,_Alloc>'
1> with
1> [
1> _Ty=LPXNode ,
1> _Alloc=std::allocator<LPXNode >
1> ]
Any suggestions?
|
|
|
|
|
see infosarang's post from Feb 2009.
|
|
|
|
|
Firstly I would like to tell you that I believe you have done a great job with this project. I particulary find it very useful.
My question is the following one:
In some cases, I need to create a XLM string containing a XML struct. I create the XML nodes and at the end get the string through GetXML(). I get the xml string correctly but containig "⎡" characters.
In some cases, this is very useful( when creating a file, it includes directly the tabs and carriage returns needed). But in some other cases, I would like to eliminate this part.
I mean, for example for the following struct generated:
<TAddressBook description='book of bro' >
<TPerson type='friend' >
<Name>Baik,Ji Hoon</Name>
<Nick>bjh</Nick>
</TPerson>
<TPerson type='friend' >
<Name>Bak,Gun Joo</Name>
<Nick>dichter</Nick>
</TPerson>
<TInformation count='3' />
</TAddressBook>
Insteado of obtaining something like this when calling GetXML()
<TAddressBook description='book of bro' >⎡⎡<TPerson type='friend' >⎡⎡⎡⎡⎡<Name>Baik,Ji⎡⎡⎡⎡⎡Hoon</Name>⎡⎡⎡⎡⎡<Nick>bjh</Nick>⎡⎡⎡⎡⎡</TPerson>⎡⎡⎡⎡⎡<TPerson type='friend' >⎡⎡⎡⎡⎡<Name>Bak,Gun Joo</Name>⎡⎡⎡⎡⎡<Nick>dichter</Nick>⎡⎡⎡⎡⎡</TPerson>⎡⎡⎡⎡⎡<TInformation count='3' />⎡⎡⎡⎡⎡</TAddressBook>
Get something like this:
<TAddressBook description='book of bro' ><TPerson type='friend' ><Name>Baik,Ji Hoon</Name><Nick>bjh</Nick></TPerson><TPerson type='friend' ><Name>Bak,Gun Joo</Name><Nick>dichter</Nick></TPerson><TInformation count='3' /></TAddressBook>
Many thanks in advance for your help
|
|
|
|
|
There is a pure C version of this XML parser? if no, is it easy to do so?
|
|
|
|
|
First, I thanks Cho, Kyung-min for this great class!
The program I build needed a parser to read a hierarhic XML file. With XMLite I can do that job. The problem is that my program is a real UNICODE application. To link in the module I have done the UNICODE conversion.
My program a UNICODE C++/MFC application running on Windows 7 which is maintained with MSVC++ 6.0 updated with the last SP's and API-libs.
The class is using the TCHAR, LPTSTR and LPCTSTR macro definitions.
It also uses the _T( ) macro for some strings but not all of them.
When using those macros, you need to recalculate the character size because in UNICODE the size of a string in bytes is not the same as the character count.
So, here is a list of what I have changed:
1. Change all literal strings from "xxxx" into _T("xxxx")
2. Change all literal chars from 'x' into _T('x')
3. Change all sizeof(szXMLPIOpen)-1 into sizeof(szXMLPIOpen)/sizeof(TCHAR)-1
4. Change all sizeof(szXMLPIClose)-1 into sizeof(szXMLPIClose)/sizeof(TCHAR)-1
5. Change all sizeof(szXMLCDATAOpen)-1 into sizeof(szXMLCDATAOpen)/sizeof(TCHAR)-1
6. Change all sizeof(szXMLCDATAClose)-1 into sizeof(szXMLCDATAClose)/sizeof(TCHAR)-1
7. Change all sizeof(szXMLCommentOpen)-1 into sizeof(szXMLCommentOpen)/sizeof(TCHAR)-1
8. Change all sizeof(szXMLCommentClose)-1 into sizeof(szXMLCommentClose)/sizeof(TCHAR)-1
9. Change all memcpy( pss, psz, len ); into memcpy( pss, psz, len * sizeof(TCHAR) );
10. Change all strchr into _tcschr
11. Change all std::ostringstream os; into std::basic_ostringstream<TCHAR> os;
These macro's make it possible to compile for ANSI or UNICODE.
What left are the settings for the preprocessor, compiler and linker.
Setup Win32 Unicode Release for VC++6.0:
Click on build->configurations.
Click add.
Type in configuration: Unicode Release.
Select in copy settings from: <project> - Win32 Release.
Click ok and close
Click on project-settings.
Select in settings for: Win32 Unicode Release.
Click on tab General.
Change content of output directories into Unicode_Release.
Change content of output files into Unicode_Release.
Click on tab C/C++.
Select category: general.
change in Preprocessor definitions _MBCS into _UNICODE,UNICODE.
Click on tab Link.
Select category: Output.
Type in Entry-point symbol: wWinMainCRTStartup.
Click on OK.
Setup Win32 Unicode Debug for VC++6.0:
Click on build->configurations.
Click add.
Type in configuration: Unicode Debug.
Select in copy settings from: <project> - Win32 Debug.
Click ok and close
Click on project-settings.
Select in settings for: Win32 Unicode Debug.
Click on tab General.
Change content of output directories into Unicode_Debug.
Change content of output files into Unicode_Debug.
Click on tab C/C++.
Select category: general.
change in Preprocessor definitions _MBCS into _UNICODE,UNICODE.
Click on tab Link.
Select category: Output.
Type in Entry-point symbol: wWinMainCRTStartup.
Click on OK.
If this can help you, please drop a line...
modified on Wednesday, April 7, 2010 4:47 AM
|
|
|
|
|
Remove the locally recreated object - attrs.
Priya Sundar
|
|
|
|
|
There is no bug!
The object attrs is automatic. When it goes out of scope, it calls the vector destructor to clear all used memory. Only if you put a pointer to allocated memory into the vector, then that memory must be deleted before calling the destructor.
|
|
|
|
|
Hello,
I am looking for the unicode version of the xmlite parser.
I went through the mailing list and tried suggested changes.
But its not working on Windows Vista using VS2008.
Pl let me know the pointer.
Thanks
G.Muruganandam
|
|
|
|
|
|
<A>
<B>
<C>
<1/>
<2/>
<3/>
</C>
</B>
</A>
Your example shows that control 3 deeps childs
I want to know that it possible to control child over 5 deeps
thanks.
|
|
|
|
|
hi, zzigee.
XMLite hasn't no limitation about deepth.
You can easily grow the deepth of tree by using AppendChild on child node recursively.
Thank you all. No one know oneself all. My idea from you, book, all others. already we are shared brains.
|
|
|
|
|
Hi,
I used XMLite in both VS2002 and VS 2005 with MFC, and now i goes with Windows CE version. Can any one used XMLite under Win CE version, then what are the necessary to change for Win CE....?
Help Needed,
Thanks in advance,
-Saran.
|
|
|
|
|
using code::blocks 8.02, GNU GCC compiler.
I get the following errors (after removing line 5 from XMLite.cpp (#include "stdafx.h"), which is a microsoft only header?
Any idea what I can do to get this to compile?
errors in XMLite.h
------------------
C:\Program Files\CodeBlocks\XMLite\XMLite.h|57|error: `LPTSTR' has not been declared|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|57|error: ISO C++ forbids declaration of `entity' with no type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|57|error: `_tagXmlEntity* _tagXMLEntitys::GetEntity(int)' and `_tagXmlEntity* _tagXMLEntitys::GetEntity(int)' cannot be overloaded|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|58|error: `LPCTSTR' has not been declared|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|58|error: ISO C++ forbids declaration of `str' with no type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|59|error: `LPCTSTR' has not been declared|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|59|error: `LPTSTR' has not been declared|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|59|error: ISO C++ forbids declaration of `estr' with no type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|59|error: ISO C++ forbids declaration of `str' with no type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|60|error: `LPCTSTR' has not been declared|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|60|error: `LPTSTR' has not been declared|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|60|error: ISO C++ forbids declaration of `str' with no type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|60|error: ISO C++ forbids declaration of `estr' with no type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|61|error: `CString' does not name a type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|62|error: `CString' does not name a type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|68|error: `CString' does not name a type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|69|error: `CString' does not name a type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|89|error: `LPTSTR' does not name a type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|91|error: `LPTSTR' does not name a type|
C:\Program Files\CodeBlocks\XMLite\XMLite.h|93|error: `CString' does not name a type|
and so on.. (50 errors all up)
thanks
|
|
|
|
|
I also tested the XMLite using gcc compiler i also gets more no. errors. don't know how to rectify this
|
|
|
|
|
|
hello,
i must say, that using Your xml parser is far more comfortable than using msxml. thank You for Your time and efforts.
nonetheless, it stroke me down, when i've noticed the number of compiler errors related to unicode compatibility (tchar.h stuff). i suggest You to pay more attention to _T() macro. otherwise, Your code simply doesn't compile.
cheers,
malleor
|
|
|
|
|
there's NO unicode version on the 'net and changes needed to be made are time-consuming. You do use _T sometimes, but generally Your code is not unicode-consious. many operations assuming sizeof(tchar)=1 result in baaad parsing.
i see work to be done. mine, unfortunately.
cheers
|
|
|
|
|
nice job,thanks for all your sharing.
|
|
|
|
|
Hi,
When i use XMLite in VC++ 2002 its works fine, but when i switch to VC++ 2005, it produces 6 errors,
std::_Vector_iterator<_Ty,_Alloc>::_Vector_iterator(const std::_Vector_iterator<_Ty,_Alloc> &)' : cannot convert parameter 1 from 'int' to 'const std::_Vector_iterator<_Ty,_Alloc> &'
with
[
_Ty=LPXNode ,
_Alloc=std::allocator<lpxnode>
]
Reason: cannot convert from 'int' to 'const std::_Vector_iterator<_Ty,_Alloc>'
with
[
_Ty=LPXNode ,
_Alloc=std::allocator<lpxnode>
]
No constructor could take the source type, or constructor overload resolution was ambiguous
</lpxnode></lpxnode>
I doesn't know the Iterator return NULL but its not supported as XNodes::iterator???
Thanks,
Saran.
|
|
|
|
|
Hi all,
I found the VC++ 2005 version of XMLite in the following location.
http://www.cogniview.com/creative-commons-info.php[^]
It compiles , but we should change the calling functions as with the above. that is the return type of node name and value as std::string, so we must change its from CString into that.
Thats all.
Thanks,
Saran.
|
|
|
|
|
//following version is edited to work for VC++ 2008 and also Unicode implemented
// XMLite.cpp: implementation of the XMLite class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XMLite.h"
#include <iostream>
#include <sstream>
#include <string>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
static const TCHAR chXMLTagOpen = '<';
static const TCHAR chXMLTagClose = '>';
static const TCHAR chXMLTagPre = '/';
static const TCHAR chXMLEscape = '\\'; // for value field escape
static const TCHAR szXMLPIOpen[] = _T("<?");
static const TCHAR szXMLPIClose[] = _T("?>");
static const TCHAR szXMLCommentOpen[] = _T("<!--");
static const TCHAR szXMLCommentClose[] = _T("-->");
static const TCHAR szXMLCDATAOpen[] = _T("<![CDATA[");
static const TCHAR szXMLCDATAClose[] = _T("]]>");
static const XENTITY x_EntityTable[] = {
{ '&', _T("&amp;"), 5 } ,
{ '\"', _T("&quot;"), 6 } ,
{ '\'', _T("&apos;"), 6 } ,
{ '<', _T("&lt;"), 4 } ,
{ '>', _T("&gt;"), 4 }
};
PARSEINFO piDefault;
DISP_OPT optDefault;
XENTITYS entityDefault((LPXENTITY)x_EntityTable, sizeof(x_EntityTable)/sizeof(x_EntityTable[0]) );
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//========================================================
// Name : _tcschrs
// Desc : same with _tcspbrk
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcschrs( LPCTSTR psz, LPCTSTR pszchs )
{
while( psz && *psz )
{
if( wcschr( pszchs, *psz ) )
return (LPTSTR)psz;
psz++;
}
return NULL;
}
//========================================================
// Name : _tcsskip
// Desc : skip space
// Param :
// Return : skiped string
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcsskip( LPCTSTR psz )
{
//while( psz && *psz == ' ' && *psz == 13 && *psz == 10 ) psz++;
while( psz && isspace(*psz) ) psz++;
return (LPTSTR)psz;
}
//========================================================
// Name : _tcsechr
// Desc : similar with _tcschr with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcsechr( LPCTSTR psz, int ch, int escape )
{
LPTSTR pch = (LPTSTR)psz;
while( pch && *pch )
{
if( escape != 0 && *pch == escape )
pch++;
else
if( *pch == ch )
return (LPTSTR)pch;
pch++;
}
return pch;
}
//========================================================
// Name : _tcselen
// Desc : similar with _tcslen with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
int _tcselen( int escape, LPTSTR srt, LPTSTR end = NULL )
{
int len = 0;
LPTSTR pch = srt;
if( end==NULL ) end = (LPTSTR)sizeof(long);
LPTSTR prev_escape = NULL;
while( pch && *pch && pch<end )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
len++;
}
pch++;
}
return len;
}
//========================================================
// Name : _tcsecpy
// Desc : similar with _tcscpy with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
void _tcsecpy( LPTSTR psz, int escape, LPTSTR srt, LPTSTR end = NULL )
{
LPTSTR pch = srt;
if( end==NULL ) end = (LPTSTR)sizeof(long);
LPTSTR prev_escape = NULL;
while( pch && *pch && pch<end )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
*psz++ = *pch;
}
pch++;
}
*psz = '\0';
}
//========================================================
// Name : _tcsepbrk
// Desc : similar with _tcspbrk with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcsepbrk( LPCTSTR psz, LPCTSTR chset, int escape )
{
LPTSTR pch = (LPTSTR)psz;
LPTSTR prev_escape = NULL;
while( pch && *pch )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
if( _tcschr( chset, *pch ) )
return (LPTSTR)pch;
}
pch++;
}
return pch;
}
//========================================================
// Name : _tcsenicmp
// Desc : similar with _tcsnicmp with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
int _tcsenicmp( LPCTSTR psz, LPCTSTR str, int len, int escape )
{
LPTSTR pch = (LPTSTR)psz;
LPTSTR prev_escape = NULL;
LPTSTR des = (LPTSTR)str;
int i = 0;
while( pch && *pch && i < len )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
if( tolower(*pch) != tolower(des[i]) )
break;
i++;
}
pch ++;
}
// find
if( i == len )
return 0;
if( psz[i] > des[i] )
return 1;
return -1;
}
//========================================================
// Name : _tcsenistr
// Desc : similar with _tcsistr with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcsenistr( LPCTSTR psz, LPCTSTR str, int len, int escape )
{
LPTSTR pch = (LPTSTR)psz;
LPTSTR prev_escape = NULL;
LPTSTR des = (LPTSTR)str;
int i = 0;
while( pch && *pch )
{
if( escape != 0 && *pch == escape && prev_escape == NULL )
prev_escape = pch;
else
{
prev_escape = NULL;
if( _tcsenicmp( pch, str, len, escape ) == 0 )
return (LPTSTR)pch;
}
pch++;
}
return pch;
}
//========================================================
// Name : _tcseistr
// Desc : similar with _tcsistr with escape process
// Param : escape - will be escape character
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tcseistr( LPCTSTR psz, LPCTSTR str, int escape )
{
int len = _tcslen( str );
return _tcsenistr( psz, str, len, escape );
}
//========================================================
// Name : _SetString
// Desc : put string of (psz~end) on ps string
// Param : trim - will be trim?
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
void _SetString( LPTSTR psz, LPTSTR end, CString* ps, bool trim = FALSE, int escape = 0 )
{
//trim
if( trim )
{
while( psz && psz < end && _istspace(*psz) ) psz++;
while( (end-1) && psz < (end-1) && _istspace(*(end-1)) ) end--;
}
int len = end - psz;
if( len <= 0 ) return;
if( escape )
{
len = _tcselen( escape, psz, end );
LPTSTR pss = ps->GetBufferSetLength( len );
_tcsecpy( pss, escape, psz, end );
}
else
{
LPTSTR pss = ps->GetBufferSetLength(len + 1 );
memcpy( pss, psz, len * sizeof(TCHAR) );
pss[len] = '\0';
}
}
_tagXMLNode::~_tagXMLNode()
{
Close();
}
void _tagXMLNode::Close()
{
int i;
for( i = 0 ; i < (int)childs.size(); i ++)
{
LPXNode p = childs[i];
if( p )
{
delete p; childs[i] = NULL;
}
}
childs.clear();
for( i = 0 ; i < (int)attrs.size(); i ++)
{
LPXAttr p = attrs[i];
if( p )
{
delete p; attrs[i] = NULL;
}
}
attrs.clear();
}
// attr1="value1" attr2='value2' attr3=value3 />
// ^- return pointer
//========================================================
// Name : LoadAttributes
// Desc : loading attribute plain xml text
// Param : pszAttrs - xml of attributes
// pi = parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tagXMLNode::LoadAttributes( LPCTSTR pszAttrs , LPPARSEINFO pi /*= &piDefault*/)
{
LPTSTR xml = (LPTSTR)pszAttrs;
while( xml && *xml )
{
if( xml = _tcsskip( xml ) )
{
// close tag
if( *xml == chXMLTagClose || *xml == chXMLTagPre )
// wel-formed tag
return xml;
// XML Attr Name
TCHAR* pEnd = _tcspbrk( xml, L" =" );
if( pEnd == NULL )
{
// error
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_ATTR_NO_VALUE;
pi->error_string.Format( _T("<%s> attribute has error "), name );
}
return NULL;
}
LPXAttr attr = new XAttr;
attr->parent = this;
// XML Attr Name
_SetString( xml, pEnd, &attr->name );
// add new attribute
attrs.push_back( attr );
xml = pEnd;
// XML Attr Value
if( xml = _tcsskip( xml ) )
{
//if( xml = _tcschr( xml, '=' ) )
if( *xml == '=' )
{
if( xml = _tcsskip( ++xml ) )
{
// if " or '
// or none quote
int quote = *xml;
if( quote == '"' || quote == '\'' )
pEnd = _tcsechr( ++xml, quote, chXMLEscape );
else
{
//attr= value>
// none quote mode
//pEnd = _tcsechr( xml, ' ', '\\' );
pEnd = _tcsepbrk( xml, _T(" >"), chXMLEscape );
}
bool trim = pi->trim_value;
TCHAR escape = pi->escape_value;
//_SetString( xml, pEnd, &attr->value, trim, chXMLEscape );
_SetString( xml, pEnd, &attr->value, trim, escape );
xml = pEnd;
// ATTRVALUE
if( pi->entity_value && pi->entitys )
attr->value = pi->entitys->Ref2Entity(attr->value);
if( quote == '"' || quote == '\'' )
xml++;
}
}
}
}
}
// not wel-formed tag
return NULL;
}
// attr1="value1" attr2='value2' attr3=value3 />
// ^- return pointer
//========================================================
// Name : LoadAttributes
// Desc : loading attribute plain xml text
// Param : pszAttrs - xml of attributes
// pszEnd - last string
// pi = parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR _tagXMLNode::LoadAttributes( LPCTSTR pszAttrs, LPCTSTR pszEnd, LPPARSEINFO pi /*= &piDefault*/ )
{
LPTSTR xml = (LPTSTR)pszAttrs;
while( xml && *xml )
{
if( xml = _tcsskip( xml ) )
{
// close tag
if( xml >= pszEnd )
// wel-formed tag
return xml;
// XML Attr Name
TCHAR* pEnd = _tcspbrk( xml, L" =" );
if( pEnd == NULL )
{
// error
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_ATTR_NO_VALUE;
pi->error_string.Format( _T("<%s> attribute has error "), name );
}
return NULL;
}
LPXAttr attr = new XAttr;
attr->parent = this;
// XML Attr Name
_SetString( xml, pEnd, &attr->name );
// add new attribute
attrs.push_back( attr );
xml = pEnd;
// XML Attr Value
if( xml = _tcsskip( xml ) )
{
//if( xml = _tcschr( xml, '=' ) )
if( *xml == '=' )
{
if( xml = _tcsskip( ++xml ) )
{
// if " or '
// or none quote
int quote = *xml;
if( quote == '"' || quote == '\'' )
pEnd = _tcsechr( ++xml, quote, chXMLEscape );
else
{
//attr= value>
// none quote mode
//pEnd = _tcsechr( xml, ' ', '\\' );
pEnd = _tcsepbrk( xml, _T(" >"), chXMLEscape );
}
bool trim = pi->trim_value;
TCHAR escape = pi->escape_value;
//_SetString( xml, pEnd, &attr->value, trim, chXMLEscape );
_SetString( xml, pEnd, &attr->value, trim, escape );
xml = pEnd;
// ATTRVALUE
if( pi->entity_value && pi->entitys )
attr->value = pi->entitys->Ref2Entity(attr->value);
if( quote == '"' || quote == '\'' )
xml++;
}
}
}
}
}
// not wel-formed tag
return NULL;
}
// <?xml version="1.0"?>
// ^- return pointer
//========================================================
// Name : LoadProcessingInstrunction
// Desc : loading processing instruction
// Param : pszXml - PI string
// pi - parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR _tagXMLNode::LoadProcessingInstrunction( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
// find the end of pi
LPTSTR end = _tcsenistr( pszXml, szXMLPIClose, sizeof(szXMLPIClose)/sizeof(TCHAR)-1, pi ? pi->escape_value : 0 );
if( end == NULL )
return NULL;
// process pi
if( doc )
{
LPTSTR xml = (LPTSTR)pszXml;
LPXNode node = new XNode;
node->parent = this;
node->doc = doc;
node->type = XNODE_PI;
xml += sizeof(szXMLPIOpen)/sizeof(TCHAR)-1;
TCHAR* pTagEnd = _tcspbrk( xml, L" ?>" );
_SetString( xml, pTagEnd, &node->name );
xml = pTagEnd;
node->LoadAttributes( xml, end, pi );
doc->childs.push_back( node );
}
end += sizeof(szXMLPIClose)/sizeof(TCHAR)-1;
return end;
}
// <!-- comment -->
// ^- return pointer
//========================================================
// Name : LoadComment
// Desc : loading comment
// Param : pszXml - comment string
// pi - parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR _tagXMLNode::LoadComment( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
// find the end of comment
LPTSTR end = _tcsenistr( pszXml, szXMLCommentClose, sizeof(szXMLCommentClose)/sizeof(TCHAR)-1, pi ? pi->escape_value : 0 );
if( end == NULL )
return NULL;
// process comment
LPXNode par = parent;
if( parent == NULL && doc )
par = (LPXNode)&doc;
if( par )
{
LPTSTR xml = (LPTSTR)pszXml;
xml += sizeof(szXMLCommentOpen)/sizeof(TCHAR)-1;
LPXNode node = new XNode;
node->parent = this;
node->doc = doc;
node->type = XNODE_COMMENT;
node->name = _T("#COMMENT");
_SetString( xml, end, &node->value, FALSE );
par->childs.push_back( node );
}
end += sizeof(szXMLCommentClose)/sizeof(TCHAR)-1;
return end;
}
// <![CDATA[ cdata ]]>
// ^- return pointer
//========================================================
// Name : LoadCDATA
// Desc : loading CDATA
// Param : pszXml - CDATA string
// pi - parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR _tagXMLNode::LoadCDATA( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
// find the end of CDATA
LPTSTR end = _tcsenistr( pszXml, szXMLCDATAClose, sizeof(szXMLCDATAClose)/sizeof(TCHAR)-1, pi ? pi->escape_value : 0 );
if( end == NULL )
return NULL;
// process CDATA
LPXNode par = parent;
if( parent == NULL && doc )
par = (LPXNode)&doc;
if( par )
{
LPTSTR xml = (LPTSTR)pszXml;
xml += sizeof(szXMLCDATAOpen)/sizeof(TCHAR)-1;
LPXNode node = new XNode;
node->parent = this;
node->doc = doc;
node->type = XNODE_CDATA;
node->name = _T("#CDATA");
_SetString( xml, end, &node->value, FALSE );
par->childs.push_back( node );
}
end += sizeof(szXMLCDATAClose)/sizeof(TCHAR)-1;
return end;
}
//========================================================
// Name : LoadOtherNodes
// Desc : internal function for loading PI/CDATA/Comment
// Param : node - current xml node
// pbRet - error occur
// pszXml - CDATA string
// pi - parser information
// Return : advanced string pointer. (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2004-06-14
//========================================================
LPTSTR LoadOtherNodes( LPXNode node, bool* pbRet, LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
LPTSTR xml = (LPTSTR)pszXml;
bool do_other_type = true;
*pbRet = false;
while( xml && do_other_type )
{
do_other_type = false;
xml = _tcsskip( xml );
LPTSTR prev = xml;
// is PI( Processing Instruction ) Node?
if( _tcsnicmp( xml, szXMLPIOpen, sizeof(szXMLPIOpen)/sizeof(TCHAR)-1 ) == 0 )
{
// processing instrunction parse
// return pointer is next node of pi
xml = node->LoadProcessingInstrunction( xml, pi );
//if( xml == NULL )
// return NULL;
// restart xml parse
}
if( xml != prev )
do_other_type = true;
xml = _tcsskip( xml );
prev = xml;
// is comment Node?
if( _tcsnicmp( xml, szXMLCommentOpen, sizeof(szXMLCommentOpen)/sizeof(TCHAR)-1 ) == 0 )
{
// processing comment parse
// return pointer is next node of comment
xml = node->LoadComment( xml, pi );
// comment node is terminal node
if( node->parent && node->parent->type != XNODE_DOC
&& xml != prev )
{
*pbRet = true;
return xml;
}
// restart xml parse when this node is root doc node
}
if( xml != prev )
do_other_type = true;
xml = _tcsskip( xml );
prev = xml;
// is CDATA Node?
if( _tcsnicmp( xml, szXMLCDATAOpen, sizeof(szXMLCDATAOpen)/sizeof(TCHAR)-1 ) == 0 )
{
// processing CDATA parse
// return pointer is next node of CDATA
xml = node->LoadCDATA( xml, pi );
// CDATA node is terminal node
if( node->parent && node->parent->type != XNODE_DOC
&& xml != prev )
{
*pbRet = true;
return xml;
}
// restart xml parse when this node is root doc node
}
if( xml != prev )
do_other_type = true;
}
return xml;
}
// <TAG attr1="value1" attr2='value2' attr3=value3 >
// </TAG>
// or
// <TAG />
// ^- return pointer
//========================================================
// Name : Load
// Desc : load xml plain text
// Param : pszXml - plain xml text
// pi = parser information
// Return : advanced string pointer (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tagXMLNode::Load( LPCTSTR pszXml, LPPARSEINFO pi /*= &piDefault*/ )
{
// Close it
Close();
LPTSTR xml = (LPTSTR)pszXml;
xml = _tcschr( xml, chXMLTagOpen );
if( xml == NULL )
return NULL;
// Close Tag
if( *(xml+1) == chXMLTagPre ) // </Close
return xml;
// Load Other Node before <Tag>(pi, comment, CDATA etc)
bool bRet = false;
LPTSTR ret = NULL;
ret = LoadOtherNodes( this, &bRet, xml, pi );
if( ret != NULL )
xml = ret;
if( bRet )
return xml;
// XML Node Tag Name Open
xml++;
TCHAR* pTagEnd = _tcspbrk( xml, L" />\t\r\n" );
_SetString( xml, pTagEnd, &name );
xml = pTagEnd;
// Generate XML Attributte List
if( xml = LoadAttributes( xml, pi ) )
{
// alone tag <TAG ... />
if( *xml == chXMLTagPre )
{
xml++;
if( *xml == chXMLTagClose )
// wel-formed tag
return ++xml;
else
{
// error: <TAG ... / >
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_ALONE_NOT_CLOSED;
pi->error_string = _T("Element must be closed.");
}
// not wel-formed tag
return NULL;
}
}
else
// open/close tag <TAG ..> ... </TAG>
// ^- current pointer
{
// if text value is not exist, then assign value
//if( this->value.IsEmpty() || this->value == _T("") )
if( XIsEmptyString( value ) )
{
// Text Value
TCHAR* pEnd = _tcsechr( ++xml, chXMLTagOpen, chXMLEscape );
if( pEnd == NULL )
{
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_NOT_CLOSED;
pi->error_string.Format(_T("%s must be closed with </%s>"), name );
}
// error cos not exist CloseTag </TAG>
return NULL;
}
bool trim = pi->trim_value;
TCHAR escape = pi->escape_value;
//_SetString( xml, pEnd, &value, trim, chXMLEscape );
_SetString( xml, pEnd, &value, trim, escape );
xml = pEnd;
// TEXTVALUE reference
if( pi->entity_value && pi->entitys )
value = pi->entitys->Ref2Entity(value);
}
// generate child nodes
while( xml && *xml )
{
LPXNode node = new XNode;
node->parent = this;
node->doc = doc;
node->type = type;
xml = node->Load( xml,pi );
if( node->name.IsEmpty() == FALSE )
{
childs.push_back( node );
}
else
{
delete node;
}
// open/close tag <TAG ..> ... </TAG>
// ^- current pointer
// CloseTag case
if( xml && *xml && *(xml+1) && *xml == chXMLTagOpen && *(xml+1) == chXMLTagPre )
{
// </Close>
xml+=2; // C
if( xml = _tcsskip( xml ) )
{
CString closename;
TCHAR* pEnd = _tcspbrk( xml, L" >" );
if( pEnd == NULL )
{
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_NOT_CLOSED;
pi->error_string.Format(_T("it must be closed with </%s>"), name );
}
// error
return NULL;
}
_SetString( xml, pEnd, &closename );
if( closename == this->name )
{
// wel-formed open/close
xml = pEnd+1;
// return '>' or ' ' after pointer
return xml;
}
else
{
xml = pEnd+1;
// 2004.6.15 - example <B> alone tag
// now it can parse with attribute 'force_arse'
if( pi->force_parse == false )
{
// not welformed open/close
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_NOT_NESTED;
pi->error_string.Format(_T("'<%s> ... </%s>' is not wel-formed."), name, closename );
}
return NULL;
}
}
}
}
else // Alone child Tag Loaded
// else ÇؾßÇÏ´ÂÁö ¸»¾Æ¾ßÇÏ´ÂÁö Àǽɰ£´Ù.
{
//if( xml && this->value.IsEmpty() && *xml !=chXMLTagOpen )
if( xml && XIsEmptyString( value ) && *xml !=chXMLTagOpen )
{
// Text Value
TCHAR* pEnd = _tcsechr( xml, chXMLTagOpen, chXMLEscape );
if( pEnd == NULL )
{
// error cos not exist CloseTag </TAG>
if( pi->erorr_occur == false )
{
pi->erorr_occur = true;
pi->error_pointer = xml;
pi->error_code = PIE_NOT_CLOSED;
pi->error_string.Format(_T("it must be closed with </%s>"), name );
}
return NULL;
}
bool trim = pi->trim_value;
TCHAR escape = pi->escape_value;
//_SetString( xml, pEnd, &value, trim, chXMLEscape );
_SetString( xml, pEnd, &value, trim, escape );
xml = pEnd;
//TEXTVALUE
if( pi->entity_value && pi->entitys )
value = pi->entitys->Ref2Entity(value);
}
}
}
}
}
return xml;
}
// <?xml version='1.0'?>
// <TAG attr1="value1" attr2='value2' attr3=value3 >
// </TAG>
// or
// <TAG />
// ^- return pointer
//========================================================
// Name : Load
// Desc : load xml plain text for xml document
// Param : pszXml - plain xml text
// pi = parser information
// Return : advanced string pointer (error return NULL)
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPTSTR _tagXMLDocument::Load( LPCTSTR pszXml, LPPARSEINFO pi /*= NULL*/ )
{
LPXNode node = new XNode;
node->parent = (LPXNode)this;
node->type = XNODE_ELEMENT;
node->doc = this;
LPTSTR end;
if( pi == NULL )
pi = &parse_info;
if( (end = node->Load( pszXml, pi )) == NULL )
{
delete node;
return NULL;
}
childs.push_back( node );
// Load Other Node after </Tag>(pi, comment, CDATA etc)
LPTSTR ret;
bool bRet = false;
ret = LoadOtherNodes( node, &bRet, end, pi );
if( ret != NULL )
end = ret;
return end;
}
LPXNode _tagXMLDocument::GetRoot()
{
XNodes::iterator it = childs.begin();
for( ; it != childs.end() ; ++(it) )
{
LPXNode node = *it;
if( node->type == XNODE_ELEMENT )
return node;
}
return NULL;
}
//========================================================
// Name : GetXML
// Desc : convert plain xml text from parsed xml attirbute
// Param :
// Return : converted plain string
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
CString _tagXMLAttr::GetXML( LPDISP_OPT opt /*= &optDefault*/ )
{
std::basic_ostringstream<TCHAR> os;
//os << (LPCTSTR)name << "='" << (LPCTSTR)value << "' ";
os << (LPCTSTR)name << L"=" << (char)opt->value_quotation_mark
<< (LPCTSTR)(opt->reference_value&&opt->entitys?opt->entitys->Entity2Ref(value):value)
<< (char)opt->value_quotation_mark << L" ";
return os.str().c_str();
}
//========================================================
// Name : GetXML
// Desc : convert plain xml text from parsed xml node
// Param :
// Return : converted plain string
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
CString _tagXMLNode::GetXML( LPDISP_OPT opt /*= &optDefault*/ )
{
std::basic_ostringstream<TCHAR> os;
// tab
if( opt && opt->newline )
{
if( opt && opt->newline )
os << L"\r\n";
for( int i = 0 ; i < opt->tab_base ; i++)
os << '\t';
}
if( type == XNODE_DOC )
{
for( int i = 0 ; i < (int)childs.size(); i++ )
os << (LPCTSTR)childs[i]->GetXML( opt );
return os.str().c_str();
}
else
if( type == XNODE_PI )
{
// <?TAG
os << szXMLPIOpen << (LPCTSTR)name;
// <?TAG Attr1="Val1"
if( attrs.empty() == false ) os << ' ';
for( int i = 0 ; i < (int)attrs.size(); i++ )
{
os << (LPCTSTR)attrs[i]->GetXML(opt);
}
//?>
os << szXMLPIClose;
return os.str().c_str();
}
else
if( type == XNODE_COMMENT )
{
// <--comment
os << szXMLCommentOpen << (LPCTSTR)value;
//-->
os << szXMLCommentClose;
return os.str().c_str();
}
else
if( type == XNODE_CDATA )
{
// <--comment
os << szXMLCDATAOpen << (LPCTSTR)value;
//-->
os << szXMLCDATAClose;
return os.str().c_str();
}
// <TAG
os << '<' << (LPCTSTR)name;
// <TAG Attr1="Val1"
if( attrs.empty() == false ) os << ' ';
for( int i = 0 ; i < (int)attrs.size(); i++ )
{
os << (LPCTSTR)attrs[i]->GetXML(opt);
}
if( childs.empty() && value.IsEmpty() )
{
// <TAG Attr1="Val1"/> alone tag
os << L"/>";
}
else
{
// <TAG Attr1="Val1"> and get child
os << '>';
if( opt && opt->newline && !childs.empty() )
{
opt->tab_base++;
}
for( int i = 0 ; i < (int)childs.size(); i++ )
os << (LPCTSTR)childs[i]->GetXML( opt );
// Text Value
if( value != _T("") )
{
if( opt && opt->newline && !childs.empty() )
{
if( opt && opt->newline )
os << L"\r\n";
for( int i = 0 ; i < opt->tab_base ; i++)
os << '\t';
}
os << (LPCTSTR)(opt->reference_value&&opt->entitys?opt->entitys->Entity2Ref(value):value);
}
// </TAG> CloseTag
if( opt && opt->newline && !childs.empty() )
{
os << L"\r\n";
for( int i = 0 ; i < opt->tab_base-1 ; i++)
os << '\t';
}
os << L"</" << (LPCTSTR)name << '>';
if( opt && opt->newline )
{
if( !childs.empty() )
opt->tab_base--;
}
}
return os.str().c_str();
}
//========================================================
// ÇÔ¼ö¸í : GetText
// ¼³ ¸í : ³ëµå Çϳª¸¦ ÅؽºÆ® ¹®ÀÚ¿·Î ¹Ýȯ
// ÀÎ ÀÚ :
// ¸®ÅÏ°ª : º¯È¯µÈ ¹®ÀÚ¿
//--------------------------------------------------------
// ÀÛ¼ºÀÚ ÀÛ¼ºÀÏ ÀÛ¼ºÀÌÀ¯
// Á¶°æ¹Î 2004-06-15
//========================================================
CString _tagXMLNode::GetText( LPDISP_OPT opt /*= &optDefault*/ )
{
std::basic_ostringstream<TCHAR> os;
if( type == XNODE_DOC )
{
for( int i = 0 ; i < (int)childs.size(); i++ )
os << (LPCTSTR)childs[i]->GetText( opt );
}
else
if( type == XNODE_PI )
{
// no text
}
else
if( type == XNODE_COMMENT )
{
// no text
}
else
if( type == XNODE_CDATA )
{
os << (LPCTSTR)value;
}
else
if( type == XNODE_ELEMENT )
{
if( childs.empty() && value.IsEmpty() )
{
// no text
}
else
{
// childs text
for( int i = 0 ; i <(int) childs.size(); i++ )
os << (LPCTSTR)childs[i]->GetText();
// Text Value
os << (LPCTSTR)(opt->reference_value&&opt->entitys?opt->entitys->Entity2Ref(value):value);
}
}
return os.str().c_str();
}
//========================================================
// Name : GetAttr
// Desc : get attribute with attribute name
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXAttr _tagXMLNode::GetAttr( LPCTSTR attrname )
{
for( int i = 0 ; i < (int)attrs.size(); i++ )
{
LPXAttr attr = attrs[i];
if( attr )
{
if( attr->name == attrname )
return attr;
}
}
return NULL;
}
//========================================================
// Name : GetAttrs
// Desc : find attributes with attribute name, return its list
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
XAttrs _tagXMLNode::GetAttrs( LPCTSTR name )
{
XAttrs attrs;
for( int i = 0 ; i < (int)attrs.size(); i++ )
{
LPXAttr attr = attrs[i];
if( attr )
{
if( attr->name == name )
attrs.push_back( attr );
}
}
return attrs;
}
//========================================================
// Name : GetAttrValue
// Desc : get attribute with attribute name, return its value
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPCTSTR _tagXMLNode::GetAttrValue( LPCTSTR attrname )
{
LPXAttr attr = GetAttr( attrname );
return attr ? (LPCTSTR)attr->value : NULL;
}
XNodes _tagXMLNode::GetChilds()
{
return childs;
}
//========================================================
// Name : GetChilds
// Desc : Find childs with name and return childs list
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
XNodes _tagXMLNode::GetChilds( LPCTSTR name )
{
XNodes nodes;
for( int i = 0 ; i < (int)childs.size(); i++ )
{
LPXNode node = childs[i];
if( node )
{
if( node->name == name )
nodes.push_back( node );
}
}
return nodes;
}
//========================================================
// Name : GetChild
// Desc : get child node with index
// Param :
// Return : NULL return if no child.
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXNode _tagXMLNode::GetChild( int i )
{
if( i >= 0 && i <(int) childs.size() )
return childs[i];
return NULL;
}
//========================================================
// Name : GetChildCount
// Desc : get child node count
// Param :
// Return : 0 return if no child
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-12-26
//========================================================
int _tagXMLNode::GetChildCount()
{
return childs.size();
}
//========================================================
// Name : GetChild
// Desc : Find child with name and return child
// Param :
// Return : NULL return if no child.
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXNode _tagXMLNode::GetChild( LPCTSTR name )
{
for( int i = 0 ; i < (int)childs.size(); i++ )
{
LPXNode node = childs[i];
if( node )
{
if( node->name == name )
return node;
}
}
return NULL;
}
//========================================================
// Name : GetChildValue
// Desc : Find child with name and return child's value
// Param :
// Return : NULL return if no child.
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPCTSTR _tagXMLNode::GetChildValue( LPCTSTR name )
{
LPXNode node = GetChild( name );
return (node != NULL)? (LPCTSTR)node->value : NULL;
}
CString _tagXMLNode::GetChildText( LPCTSTR name, LPDISP_OPT opt /*= &optDefault*/ )
{
LPXNode node = GetChild( name );
return (node != NULL)? node->GetText(opt) : _T("");
}
LPXAttr _tagXMLNode::GetChildAttr( LPCTSTR name, LPCTSTR attrname )
{
LPXNode node = GetChild(name);
return node ? node->GetAttr(attrname) : NULL;
}
LPCTSTR _tagXMLNode::GetChildAttrValue( LPCTSTR name, LPCTSTR attrname )
{
LPXAttr attr = GetChildAttr( name, attrname );
return attr ? (LPCTSTR)attr->value : NULL;
}
//========================================================
// Name : Find
// Desc : find node with tag name from it's all childs
// Param :
// Return : NULL return if no found node.
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXNode _tagXMLNode::Find( LPCTSTR name )
{
XNodes::iterator it = childs.begin();
for( ; it != childs.end(); ++(it))
{
LPXNode child = *it;
if( child->name == name )
return child;
XNodes::iterator it = child->childs.begin();
for( ; it != child->childs.end(); ++(it))
{
LPXNode find = child->Find( name );
if( find != NULL )
return find;
}
}
return NULL;
}
//========================================================
// Name : GetChildIterator
// Desc : get child nodes iterator
// Param :
// Return : NULL return if no childs.
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
XNodes::iterator _tagXMLNode::GetChildIterator( LPXNode node )
{
XNodes::iterator it = childs.begin();
for( ; it != childs.end() ; ++(it) )
{
if( *it == node )
return it;
}
*it = NULL;
return it;
}
//========================================================
// Name : AppendChild
// Desc : add node
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXNode _tagXMLNode::AppendChild( LPCTSTR name /*= NULL*/, LPCTSTR value /*= NULL*/ )
{
return AppendChild( CreateNode( name, value ) );
}
//========================================================
// Name : AppendChild
// Desc : add node
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXNode _tagXMLNode::AppendChild( LPXNode node )
{
node->parent = this;
node->doc = doc;
childs.push_back( node );
return node;
}
//========================================================
// Name : RemoveChild
// Desc : detach node and delete object
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
bool _tagXMLNode::RemoveChild( LPXNode node )
{
XNodes::iterator it = GetChildIterator( node );
if( *it )
{
delete *it;
childs.erase( it );
return true;
}
return false;
}
//========================================================
// Name : GetAttr
// Desc : get attribute with index in attribute list
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXAttr _tagXMLNode::GetAttr( int i )
{
if( i >= 0 && i < (int)attrs.size() )
return attrs[i];
return NULL;
}
//========================================================
// Name : GetAttrIterator
// Desc : get attribute iterator
// Param :
// Return : std::vector<LPXAttr>::iterator
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
XAttrs::iterator _tagXMLNode::GetAttrIterator( LPXAttr attr )
{
XAttrs::iterator it = attrs.begin();
for( ; it != attrs.end() ; ++(it) )
{
if( *it == attr )
return it;
}
*it = NULL;
return it;
}
//========================================================
// Name : AppendAttr
// Desc : add attribute
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXAttr _tagXMLNode::AppendAttr( LPXAttr attr )
{
attr->parent = this;
attrs.push_back( attr );
return attr;
}
//========================================================
// Name : RemoveAttr
// Desc : detach attribute and delete object
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
bool _tagXMLNode::RemoveAttr( LPXAttr attr )
{
XAttrs::iterator it = GetAttrIterator( attr );
if( *it )
{
delete *it;
attrs.erase( it );
return true;
}
return false;
}
//========================================================
// Name : CreateNode
// Desc : Create node object and return it
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXNode _tagXMLNode::CreateNode( LPCTSTR name /*= NULL*/, LPCTSTR value /*= NULL*/ )
{
LPXNode node = new XNode;
node->name = name;
node->value = value;
return node;
}
//========================================================
// Name : CreateAttr
// Desc : create Attribute object and return it
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXAttr _tagXMLNode::CreateAttr( LPCTSTR name /*= NULL*/, LPCTSTR value /*= NULL*/ )
{
LPXAttr attr = new XAttr;
attr->name = name;
attr->value = value;
return attr;
}
//========================================================
// Name : AppendAttr
// Desc : add attribute
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXAttr _tagXMLNode::AppendAttr( LPCTSTR name /*= NULL*/, LPCTSTR value /*= NULL*/ )
{
return AppendAttr( CreateAttr( name, value ) );
}
//========================================================
// Name : DetachChild
// Desc : no delete object, just detach in list
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXNode _tagXMLNode::DetachChild( LPXNode node )
{
XNodes::iterator it = GetChildIterator( node );
if( *it )
{
childs.erase( it );
return node;
}
return NULL;
}
//========================================================
// Name : DetachAttr
// Desc : no delete object, just detach in list
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXAttr _tagXMLNode::DetachAttr( LPXAttr attr )
{
XAttrs::iterator it = GetAttrIterator( attr );
if( *it )
{
attrs.erase( it );
return attr;
}
return NULL;
}
//========================================================
// Name : CopyNode
// Desc : copy current level node with own attributes
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
void _tagXMLNode::CopyNode( LPXNode node )
{
Close();
doc = node->doc;
parent = node->parent;
name = node->name;
value = node->value;
type = node->type;
// copy attributes
for( int i = 0 ; i < (int)node->attrs.size(); i++)
{
LPXAttr attr = node->attrs[i];
if( attr )
AppendAttr( attr->name, attr->value );
}
}
//========================================================
// Name : _CopyBranch
// Desc : recursive internal copy branch
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
void _tagXMLNode::_CopyBranch( LPXNode node )
{
CopyNode( node );
for( int i = 0 ; i < (int)node->childs.size(); i++)
{
LPXNode child = node->childs[i];
if( child )
{
LPXNode mychild = new XNode;
mychild->CopyNode( child );
AppendChild( mychild );
mychild->_CopyBranch( child );
}
}
}
//========================================================
// Name : AppendChildBranch
// Desc : add child branch ( deep-copy )
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
LPXNode _tagXMLNode::AppendChildBranch( LPXNode node )
{
LPXNode child = new XNode;
child->CopyBranch( node );
return AppendChild( child );
}
//========================================================
// Name : CopyBranch
// Desc : copy branch ( deep-copy )
// Param :
// Return :
//--------------------------------------------------------
// Coder Date Desc
// bro 2002-10-29
//========================================================
void _tagXMLNode::CopyBranch( LPXNode branch )
{
Close();
_CopyBranch( branch );
}
_tagXMLEntitys::_tagXMLEntitys( LPXENTITY entities, int count )
{
for( int i = 0; i < count; i++)
push_back( entities[i] );
}
LPXENTITY _tagXMLEntitys::GetEntity( int entity )
{
for( int i = 0 ; i <(int) size(); i ++ )
{
if( at(i).entity == entity )
return LPXENTITY(&at(i));
}
return NULL;
}
LPXENTITY _tagXMLEntitys::GetEntity( LPTSTR entity )
{
for( int i = 0 ; i < (int)size(); i ++ )
{
LPTSTR ref = (LPTSTR)at(i).ref;
LPTSTR ps = entity;
while( ref && *ref )
if( *ref++ != *ps++ )
break;
if( ref && !*ref ) // found!
return LPXENTITY(&at(i));
}
return NULL;
}
int _tagXMLEntitys::GetEntityCount( LPCTSTR str )
{
int nCount = 0;
LPTSTR ps = (LPTSTR)str;
while( ps && *ps )
if( GetEntity( *ps++ ) ) nCount ++;
return nCount;
}
int _tagXMLEntitys::Ref2Entity( LPCTSTR estr, LPTSTR str, int strlen )
{
LPTSTR pes = (LPTSTR)estr;
LPTSTR ps = str;
LPTSTR ps_end = ps+strlen;
while( pes && *pes && ps < ps_end )
{
LPXENTITY ent = GetEntity( pes );
if( ent )
{
// copy entity meanning char
*ps = ent->entity;
pes += ent->ref_len;
}
else
*ps = *pes++; // default character copy
ps++;
}
*ps = '\0';
// total copied characters
return ps-str;
}
int _tagXMLEntitys::Entity2Ref( LPCTSTR str, LPTSTR estr, int estrlen )
{
LPTSTR ps = (LPTSTR)str;
LPTSTR pes = (LPTSTR)estr;
LPTSTR pes_end = pes+estrlen;
while( ps && *ps && pes < pes_end )
{
LPXENTITY ent = GetEntity( *ps );
if( ent )
{
// copy entity string
LPTSTR ref = (LPTSTR)ent->ref;
while( ref && *ref )
*pes++ = *ref++;
}
else
*pes++ = *ps; // default character copy
ps++;
}
*pes = '\0';
// total copied characters
return pes-estr;
}
CString _tagXMLEntitys::Ref2Entity( LPCTSTR estr )
{
CString es;
if( estr )
{
int len = _tcslen(estr);
LPTSTR esbuf = es.GetBufferSetLength( len+1 );
if( esbuf )
Ref2Entity( estr, esbuf, len );
}
return es;
}
CString _tagXMLEntitys::Entity2Ref( LPCTSTR str )
{
CString s;
if( str )
{
int nEntityCount = GetEntityCount(str);
if( nEntityCount == 0 )
return CString(str);
int len = _tcslen(str) + nEntityCount*10 ;
LPTSTR sbuf = s.GetBufferSetLength( len+1 );
if( sbuf )
Entity2Ref( str, sbuf, len );
}
return s;
}
CString XRef2Entity( LPCTSTR estr )
{
return entityDefault.Ref2Entity( estr );
}
CString XEntity2Ref( LPCTSTR str )
{
return entityDefault.Entity2Ref( str );
}
|
|
|
|
|