我的这个解析xml的程序是个对话框程序,上面就有一个树控件和一个输入路径的编辑框,再就是一个确定按钮。输入xml文件的路径后,点击确定,就能把xml文件解析出来,然后值全部放入树控件中,可是不知为什么,当xml文件中包含着中文的时候总是报告如下错误:
Debug assertion failed!
program:
file:f:\fp\vctools\crt_bld\self_x86_crt\src\vcprintf.c
line:234
expression:string != NULL && sizeInByte > 0
解析xml文件至树控件的c++程序代码如下:
#include "stdafx.h"
#include "xmlparser.h"
#include "XmlParserDlg.h"#include <atlbase.h>#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CXmlParserDlg dialogIMPLEMENT_DYNAMIC(CXmlParserDlg, CDialog);CXmlParserDlg::CXmlParserDlg(CWnd* pParent /*=NULL*/)
: CDialog(CXmlParserDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CXmlParserDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
}CXmlParserDlg::~CXmlParserDlg()
{
}void CXmlParserDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CXmlParserDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CXmlParserDlg, CDialog)
//{{AFX_MSG_MAP(CXmlParserDlg)
ON_BN_CLICKED(IDC_GOBTN, OnGo)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CXmlParserDlg message handlersBOOL CXmlParserDlg::OnInitDialog()
{
CDialog::OnInitDialog();

//
// Load the bitmap IDB_TREE into the tree control.
//
CImageList imgTree;
imgTree.Create(IDB_TREE,16,0,RGB(255,51,255));
CTreeCtrl *pTree = static_cast<CTreeCtrl*>(GetDlgItem(IDC_XMLTREE));
if ( pTree )
{
pTree->SetImageList(&imgTree,TVSIL_NORMAL);
imgTree.Detach();
} return TRUE;  // return TRUE  unless you set the focus to a control
}
///////////////////////////////////////////////////////////////////////////////
// OnGo
//
// This command is fired when the user selects the "Process" button.
//
void CXmlParserDlg::OnGo() 
{
//
// Check the file specified exists.
//
CString strFileName;
CEdit *pEdit = static_cast<CEdit*>(GetDlgItem(IDC_EDIT1));
if ( pEdit )
pEdit->GetWindowText(strFileName); //
// Assuming it's not an empty string, try to process.
//
if ( !strFileName.IsEmpty() )
{ if ( SUCCEEDED(CoInitialize(NULL)) )
{
IXMLDOMDocument *pDoc;
if ( SUCCEEDED (CoCreateInstance(CLSID_DOMDocument,
NULL,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument,
reinterpret_cast<void**>(&pDoc))))
{
//
// Tell the "doc" that we're not going to load asynchronously.
//
if ( SUCCEEDED(pDoc->put_async(VARIANT_FALSE)) )
{
CComVariant vFile(strFileName);
VARIANT_BOOL vBool;
pDoc->load(vFile,&vBool);
if ( vBool == VARIANT_TRUE )
{
IXMLDOMNode *pNode;
if ( SUCCEEDED(pDoc->QueryInterface(IID_IXMLDOMNode, 
   reinterpret_cast<void**>(&pNode))))
{
CTreeCtrl *pTree = static_cast<CTreeCtrl*>(GetDlgItem(IDC_XMLTREE)); HTREEITEM hItem = pTree->GetChildItem(TVI_ROOT);
while( hItem != NULL )
{
HTREEITEM hNext = pTree->GetNextSiblingItem(hItem);
pTree->DeleteItem(hItem);
hItem = hNext;
}

IterateChildNodes(pNode,pTree);
pNode->Release();
pNode = NULL;
}
}
else
CheckLoad(pDoc);
}
pDoc->Release();
pDoc = NULL;
}
CoUninitialize();
}
}
}///////////////////////////////////////////////////////////////////////////////
// CheckLoad                              
//
// Ensure an XML document loaded correctly.
//
HRESULT CXmlParserDlg::CheckLoad(IXMLDOMDocument *pDoc)
{
HRESULT hResult = E_FAIL;
long lErrorCode = E_FAIL;
IXMLDOMParseError *pXMLError = NULL; if (SUCCEEDED(pDoc->get_parseError(&pXMLError)) 
 && SUCCEEDED(pXMLError->get_errorCode(&lErrorCode))
 && ( lErrorCode != 0 ) )
hResult = ReportError(pXMLError); //
// Clean-up pointers used.
//
if ( pXMLError )
{
pXMLError->Release();
pXMLError = NULL;
} //
// Pass back the return code.
//
return lErrorCode;
}
///////////////////////////////////////////////////////////////////////////////
// ReportError
//
// Standardised reporting mechanism for COM errors to do with XML.
//
HRESULT CXmlParserDlg::ReportError(IXMLDOMParseError *pXMLError)
{
long lLine;
long lLinePos;
long lErrorCode;
BSTR bstrFile;
BSTR bstrReason; //
// Whilst these could all return errors, we'll assume that since the
// COM was awake enough to report an error (and return the structure)
// that it can work with these calls.
//
pXMLError->get_line(&lLine);
pXMLError->get_linepos(&lLinePos);
pXMLError->get_errorCode(&lErrorCode);
pXMLError->get_reason(&bstrReason);
pXMLError->get_url(&bstrFile); //
// Format this message into a suitable output.
//
if ( lLine > 0 )
{
CString strError;
strError.Format(_T("Error processing XML file: %S\nError on line %d, position %d\n")
             _T("Error (%x) text: %S"), 
 bstrFile, 
 lLine, lLinePos, lErrorCode, 
 bstrReason);
MessageBox(strError,_T("Parse Error"),MB_OK|MB_ICONERROR);
TRACE(_T("%s\n"),strError);
} SysFreeString(bstrFile);
SysFreeString(bstrReason);

return NOERROR;
}

解决方案 »

  1.   


    ///////////////////////////////////////////////////////////////////////////////
    // WalkTopLevel
    //
    bool CXmlParserDlg::IterateChildNodes(IXMLDOMNode *pNode, 
      CTreeCtrl *pTree, 
      HTREEITEM hParent)
    {
    BSTR bstrNodeName;
    HTREEITEM hCurrentItem; if ( pTree )
    {
    if ( pNode )
    {
    CString strOutput;
    pNode->get_nodeName(&bstrNodeName); //
    // Find out the node type (as a string).
    //
    BSTR bstrNodeType;
    pNode->get_nodeTypeString(&bstrNodeType);
    CString strType;
    strType.Format(_T("%S"),bstrNodeType);
    SysFreeString(bstrNodeType); DOMNodeType eEnum;
    pNode->get_nodeType(&eEnum); int nImg = 0; CString strValue;
    if ( eEnum == NODE_TEXT )
    {
    BSTR bstrValue;
    pNode->get_text(&bstrValue);
    strOutput.Format(_T("%S"),bstrValue);
    SysFreeString(bstrValue); nImg = 2;
    }
    else if ( eEnum == NODE_COMMENT )
    {
    VARIANT vValue;
    pNode->get_nodeValue(&vValue);

    CString strValue;
    if ( vValue.vt == VT_BSTR )
    strOutput.Format(_T("%S"),V_BSTR(&vValue));
    else
    strOutput.Format(_T("Unknown comment type"));
    VariantClear(&vValue); nImg = 3;
    }
    else if ( eEnum == NODE_PROCESSING_INSTRUCTION )
    {
    strOutput.Format(_T("%S"), bstrNodeName);
    nImg = 4;
    }
    else if ( eEnum == NODE_ELEMENT )
    {
    strOutput.Format(_T("%S"), bstrNodeName);
    nImg = 5;
    }
    else
    {
    // 
    // Other types, include the type name.
    //
    strOutput.Format(_T("%S - %s"), bstrNodeName,strType);
    }
    SysFreeString(bstrNodeName); //
    // Add it to the tree view.
    //
    TVINSERTSTRUCT tvItem;
    tvItem.hParent = hParent ? hParent : TVI_ROOT;
    tvItem.hInsertAfter = TVI_LAST;
    tvItem.item.iImage = nImg;
    tvItem.item.iSelectedImage = nImg;
    tvItem.item.pszText = strOutput.GetBuffer(MAX_PATH);
    tvItem.item.cchTextMax = MAX_PATH;
    tvItem.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
    hCurrentItem = pTree->InsertItem(&tvItem);
    strOutput.ReleaseBuffer(); IterateAttibutes(pNode, pTree, hCurrentItem);
    }
    } //
    // Any child nodes of this node need displaying too.
    //
    IXMLDOMNode *pNext = NULL;
    IXMLDOMNode *pChild;
    pNode->get_firstChild(&pChild);
    while( pChild )
    {
    IterateChildNodes(pChild,pTree,hCurrentItem);
    pChild->get_nextSibling(&pNext);
    pChild->Release();
    pChild = pNext;
    } //
    // Ensure after all of that, the item is expanded!
    //
    pTree->Expand(hCurrentItem,TVE_EXPAND);
    return true;
    }
    ///////////////////////////////////////////////////////////////////////////////
    // IterateAttibutes
    //
    bool CXmlParserDlg::IterateAttibutes(IXMLDOMNode *pNode, 
     CTreeCtrl *pTree, 
     HTREEITEM  hCurrentItem)
    {
    IXMLDOMNamedNodeMap *pAttrs; if ( SUCCEEDED(pNode->get_attributes(&pAttrs)) && (pAttrs != NULL) )
    {
    IXMLDOMNode *pChild;
    pAttrs->nextNode(&pChild);
    while(pChild)
    {
    BSTR bstrName;
    VARIANT vValue;

    pChild->get_nodeName(&bstrName);
    pChild->get_nodeValue(&vValue);

    CString strValue;
    switch ( vValue.vt )
    {
    case VT_BSTR:
    strValue.Format(_T("%S"),V_BSTR(&vValue));
    break;
    default:
    strValue = _T("Unsupport type");
    break;
    }

    CString strAttrib;
    strAttrib.Format(_T("%S=%s"),bstrName,strValue);
    SysFreeString(bstrName);
    VariantClear(&vValue);

    pChild->Release();
    pAttrs->nextNode(&pChild);

    //
    // Add the attributes to the tree too.
    //
    TVINSERTSTRUCT tvAttribItem;
    tvAttribItem.hParent = hCurrentItem;
    tvAttribItem.hInsertAfter = TVI_LAST;
    tvAttribItem.item.iImage = 1;
    tvAttribItem.item.iSelectedImage = 1;
    tvAttribItem.item.pszText = strAttrib.GetBuffer(MAX_PATH);
    tvAttribItem.item.cchTextMax = MAX_PATH;
    tvAttribItem.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
    pTree->InsertItem(&tvAttribItem);
    strAttrib.ReleaseBuffer();
    }
    pAttrs->Release();
    }
    return true;
    }
      

  2.   

    XML示例:
    <?xml version="1.0" encoding="utf-8"?>
    <wml>
    <card>湾保钓
    <br/>
    <br/><img src="http://wap.rerert.cn/resource/GD/GUANGZHOU/nfzm/7614/100-7614-0-0-0.png" alt="" />
    <br/>月岛方向。
    <br/>
    <br/>这
    <br/>川
    <br/>低头
    <br/>谢罪。
    <br/>开
    <br/>航行
    <br/>间回到了38
    <br/><a href="http://wap.ertertet.cn/content?newsid=62031&amp;uid=0&amp;from=kjava&amp;newspp=2&amp;pp=0&amp;fontsize=500&amp;action=">下一页</a>
    <br/>1/8
    <br/>
    <br/><a href="" type="close">关闭</a>
    <br/>
    </card>
    </wml>
      

  3.   

    XML中的 <>左右尖括号 需要使用转义符
      

  4.   

    这个本来就是非标准的XML,“湾保钓”属于Card,“月岛方向。”也属于Card,但是他们中间却有一些子元素进行分隔,那么这个对于解析器处理的时候,很有可能就认为为非法。
      

  5.   

    如果你想把网页的代码保存到xml里面,建议你先把网页的代码转换为16进制,然后放入xml,取出后再转回来
      

  6.   

    谢。这个xml中如果把所有的中文替换成英文,我上面的源代码也没有问题。还有,解析其它标准的xml文件时,如果xml里面有中文汉字的时候,也不能解析成功?也是同样的错误提示。就是中文xml内容不能解析,真是奇怪了。
      

  7.   

    解析XML,最好是先全部转换成Unicode(根据Encoding).
      

  8.   

    请问 解析XML,最好是先全部转换成Unicode(根据Encoding)?请问是怎么转?在程序里面用代码转吗?
      

  9.   

    <a href="http://wap.ertertet.cn/content?newsid=62031&amp;uid=0&amp;from=kjava&amp;newspp=2&amp;pp=0&amp;fontsize=500&amp;action="/>少了个 “/”吧。
      

  10.   

    上面错了。你看看你原始文本的实际编码是否是UTF-8的?
      

  11.   

    原始编码是utf8的。你的意思是什么?如果是的话就怎么样?不是的话怎么处理?
      

  12.   

    把card内容都放到CDATA中<?xml version="1.0" encoding="utf-8"?>
    <wml>
    <card><![CDATA[湾保钓
    <br/>
    <br/><img src="http://wap.rerert.cn/resource/GD/GUANGZHOU/nfzm/7614/100-7614-0-0-0.png" alt="" />
    <br/>月岛方向。
    <br/>
    <br/>这
    <br/>川
    <br/>低头
    <br/>谢罪。
    <br/>开
    <br/>航行
    <br/>间回到了38
    <br/><a href="http://wap.ertertet.cn/content?newsid=62031&amp;uid=0&amp;from=kjava&amp;newspp=2&amp;pp=0&amp;fontsize=500&amp;action=">下一页</a>
    <br/>1/8
    <br/>
    <br/><a href="" type="close">关闭</a>
    <br/>
    ]]></card>
    </wml>
      

  13.   

    先谢谢。不过还是提示那个错误。我怀疑是那个解xml程序的问题。
      

  14.   

    参考这本书看 http://d.download.csdn.net/down/187856/cw550284
      

  15.   

    用CMarkup解析一下试试
    http://www.firstobject.com/