Автор |
Сообщение |
[ZooM].Extrim
Гость
|
[6283]
Чт Окт 07, 2004 16:22
Parsing-On-Fly
Есть такая проблема: необходимо производить парсинг XML, причём документ передаётся кусками, например по 1-16 символов, парсинг должен происходить по мере поступления документа. Для таких нужд я написал свой парсер, только он далёк от совершенства. Подскажите если кто-то знает, можна ли сделать такое с помощью стандартных парсеров DOM или SAX?
|
flax
Аспирант
Зарегистрирован: 31.01.2003
Сообщения: 100
Откуда: Minsk
|
[6284]
Чт Окт 07, 2004 17:54
Такое чувство, что-то близкое уже должно быть разработано
(looking for конференции)
|
olpa
Любитель
Зарегистрирован: 23.04.2002
Сообщения: 981
Откуда: Санкт-Петербург
|
[6285]
Чт Окт 07, 2004 18:09
Мне кажется, что любой SAX-парсер должен работать именно так.
|
flax
Аспирант
Зарегистрирован: 31.01.2003
Сообщения: 100
Откуда: Minsk
|
[6286]
Пт Окт 08, 2004 09:34
Хм. Или при небольшой модификации.
Ведь если 16 символ попал на середину
Код:
<item>
1233456789011213141516
а потом с _хорошей задержкой_ (или даже закрыли тот ... сокет например)
то надо будет просто не закрывать stream SAX при закрытии (или долгом expired time ) канала поступления.
Например - еще хуже
т.е. в простом случае парсер бы дождался бы еще этих двух символов и сгенерировал
end(item), а так ему придется ...ждать дольше.
PS Ясно выразился?
PPS А если все идет более-менее гладко - то, действительно, SAX вам в руки.
PPPS А если заранее известно сколько символов идет на вход - то тут можно соптимизировать.
PPPPS А может мне все кажется?
|
[ZooM]
Гость
|
[6293]
Пн Окт 11, 2004 11:01
Ничего лучше такого решения я придумать не смог
class my_stream:public IStream,public IUnknown
{
ULONG refs;
public:
my_stream()
{
refs = 0;
}
HRESULT STDMETHODCALLTYPE QueryInterface(/* [in] */ REFIID riid,
/* [iid_is][out] */ void **ppvObject)
{
cout<<"Query CALL "<<endl;
if (riid ==__uuidof(IUnknown))
{
*ppvObject = dynamic_cast<IUnknown *>(this);
AddRef();
}
else
if (riid==__uuidof(IStream))
{
*ppvObject = this;
AddRef();
}
else
{
ppvObject = 0;
return E_NOINTERFACE;
}
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef ()
{
refs++;
return refs;
}
ULONG STDMETHODCALLTYPE Release()
{
refs--;
return refs;
}
HRESULT _stdcall Read(void* pv,ULONG cb,ULONG* pcbRead)
{
char c = getc();
*pv = (void *)c;
*pcbRead = strlen(text);
return S_OK;
}
HRESULT _stdcall Write(void const* pv,ULONG cb,ULONG* pcbWritten)
{
*pcbWritten = 0;
return S_OK;
}
HRESULT _stdcall Seek(LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER* plibNewPosition)
{
plibNewPosition = 0;
return S_OK;
}
HRESULT _stdcall SetSize(ULARGE_INTEGER libNewSize)
{
return S_OK;
}
HRESULT _stdcall CopyTo(IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten)
{
return S_OK;
}
HRESULT _stdcall Commit(DWORD grfCommitFlags)
{
return S_OK;
}
HRESULT _stdcall Revert()
{
return S_OK;
}
HRESULT _stdcall LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
return S_OK;
}
HRESULT _stdcall UnlockRegion(ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)
{
return S_OK;
}
HRESULT _stdcall Stat(STATSTG* pstatstg, DWORD grfStatFlag)
{
pstatstg->pwcsName = 0;
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize.QuadPart = 100;
pstatstg->grfLocksSupported = LOCK_WRITE;
return S_OK;
}
HRESULT _stdcall Clone(IStream** ppstm)
{
return S_OK;
}
};
int main(int argc, char* argv[])
{
CoInitialize(NULL);
ISAXXMLReader* pRdr = NULL;
HRESULT hr = CoCreateInstance(
__uuidof(SAXXMLReader),
NULL,
CLSCTX_ALL,
__uuidof(ISAXXMLReader),
(void **)&pRdr);
if(!FAILED(hr))
{
MyContent * pMc = new MyContent();
hr = pRdr->putContentHandler(pMc);
SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl();
hr = pRdr->putErrorHandler(pEc);
my_stream c;
pRdr->parse (CComVariant(&c));
pRdr->Release();
}
else
{
printf("\nError %08X\n\n", hr);
}
CoUninitialize();
return 0;
}
|