xmlhack.ru XML-форумы
Обсуждение XML и связанных с ним технологий

Parsing-On-Fly


Автор Сообщение
[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


а потом с _хорошей задержкой_ (или даже закрыли тот ... сокет например)

Код:


1718
</item>



то надо будет просто не закрывать stream SAX при закрытии (или долгом expired time ) канала поступления.
Например - еще хуже

Код:


1231231гщ</ite


т.е. в простом случае парсер бы дождался бы еще этих двух символов и сгенерировал
end(item), а так ему придется ...ждать дольше.


PS Ясно выразился? Wink
PPS А если все идет более-менее гладко - то, действительно, SAX вам в руки.
PPPS А если заранее известно сколько символов идет на вход - то тут можно соптимизировать.
PPPPS А может мне все кажется?
[ZooM]
Гость




[6293] Пн Окт 11, 2004 11:01

Ничего лучше такого решения я придумать не смог Smile

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;
}