При анализе содержимого wchar_t на платформе win32, quickxml может вызывать исключение parse_error. Содержание:rapidxml throws exception on wchar_t content
<xml att='最好' />
Вот мой код тестирования:
/*
* @file : TestRapidXmlBug.cpp
* @author: shilyx
* @date : 2015-09-16 11:02:22.886
* @note : Generated by SlxTemplates
*/
#include <Windows.h>
#include "rapidxml.hpp"
#include <iostream>
#include <string>
using namespace std;
using namespace rapidxml;
int main(int argc, char *argv[])
{
// data block
unsigned char szData[] = {
0x3C, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00, 0x20, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x3D,
0x00, 0x27, 0x00, 0x00, 0x67, 0x7D, 0x59, 0x27, 0x00, 0x20, 0x00, 0x2F, 0x00, 0x3E, 0x00, 0x00, 0x00};
// uft8 string
char szDataUtf8[sizeof(szData) * 10] = "";
// ucs2 string
wchar_t *szDataUcs2 = (wchar_t *)szData;
WideCharToMultiByte(CP_UTF8, 0, szDataUcs2, -1, szDataUtf8, sizeof(szDataUtf8), NULL, NULL);
try
{
xml_document<wchar_t> xml;
cout<<"-------------------------wchar_t"<<endl;
xml.parse<0>(szDataUcs2); // will throw parse_error
cout<<"success"<<endl;
}
catch (parse_error &ex)
{
cout<<"exception: "<<ex.what()<<endl;
cout<<"failled"<<endl;
}
try
{
xml_document<char> xml;
cout<<"-------------------------char"<<endl;
xml.parse<0>(szDataUtf8); // will not throw any exception
cout<<"success"<<endl;
}
catch (parse_error &ex)
{
cout<<ex.what()<<endl;
cout<<"failled"<<endl;
}
return 0;
}
Это выбросит исключение по адресу:
// Make sure that end quote is present
if (*text != quote)
RAPIDXML_PARSE_ERROR("expected ' or \"", text);
++text; // Skip quote
Причиной может быть:
// Skip characters until predicate evaluates to true
template<class StopPred, int Flags>
static void skip(Ch *&text)
{
Ch *tmp = text;
while (StopPred::test(*tmp))
++tmp;
text = tmp;
}
В StopPred :: Функциональный тест:
// Detect attribute value character
template<Ch Quote>
struct attribute_value_pure_pred
{
static unsigned char test(Ch ch)
{
if (Quote == Ch('\''))
return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast<unsigned char>(ch)];
if (Quote == Ch('\"'))
return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast<unsigned char>(ch)];
return 0; // Should never be executed, to avoid warnings on Comeau
}
};
static_cast изменяет wchar_t (0x6700) к беззнаковым символам (0x00), операция пропуска остановлена.
Это ошибка? или неправильно использовать quickxml с wchar_t? Дата последнего обновления rapidxml - 2013-04-26, я думаю, он должен быть достаточно стабильным.
Спасибо, но здесь я не могу использовать utf-8. Я обнаружил, что нет проблем с rapidxml.hpp в boost, возможно, я должен выбрать эту версию. Благодарю. – shilyx
@shilyx Я сомневаюсь, что что-то изменит, насколько я могу сказать, что boost_tree использует quickxml под капотом. – user657267