Невозможно прочитать строку XML с xmllite, используя буфер памяти - PullRequest
0 голосов
/ 10 января 2012

Я пытаюсь открыть поток в памяти для использования с библиотекой xmllite.Писать одному хорошо, но чтение одного доставляет мне трудности.Ниже приведен код, который я использую.В основном я создаю строку XML по умолчанию (LPWSTR) и записываю ее в поток памяти, используя CreateStreamOnHGlobal.Затем я стремлюсь к началу и читаю его обратно, чтобы убедиться, что оно там (оно есть).Затем я снова ищу и назначаю его на вход читателя.Он никогда не выходит за пределы строки:

while (S_OK == (hr = pReader->Read(&nodeType)))

Я получаю XmlNodeType_None и значение HRESULT -1072894427.Я считаю, что это затрудняет чтение потока, но я точно не знаю.Тот же код работает нормально, если вместо этого я использую файловый поток, а запись в xml из потока памяти также работает

HRESULT hr = S_OK;  CComPtr<IStream> pStream = NULL;
IXmlReader *pReader = NULL;
XmlNodeType nodeType;

LPWSTR pwszXMLString = 
    L"<?xml version\"1.0\" encoding=\"UTF-8\" ?>\r\n"
    L"<paramlist name=\"LP\">\r\n"
        L"<value></value>\r\n"
        L"<value></value>\r\n"
    L"</paramlist>\r\n"
    L"<param name=\"AutoConnect\">false</param>\r\n"
    L"<param name=\"ConnectWhenLit\">false</param>\r\n"
    L"<param name=\"SessionMaxBytes\">200000</param>\r\n"
    L"<param name=\"SessionTimeoutSecs\">300</param>\r\n"
    L"<param name=\"PacketDelayMs\">0</param>\r\n"
    L"<param name=\"PacketSizeBytes\">4096</param>\r\n"
    L"<param name=\"LowSSLSecurity\">true</param>\r\n";

DWORD dwWritten = 0;
hr = CreateStreamOnHGlobal(NULL, FALSE, &pStream);
hr = pStream->Write(pwszXMLString, wcslen(pwszXMLString) * sizeof(WCHAR), &dwWritten);

// print out the contents of the memory stream just to make sure we have it
LARGE_INTEGER pos;
pos.QuadPart = 0;
pStream->Seek(pos, STREAM_SEEK_SET, NULL);
STATSTG ssStreamData = {0};
pStream->Stat(&ssStreamData, STATFLAG_NONAME);
SIZE_T cbSize = ssStreamData.cbSize.LowPart;
LPWSTR pwszContent = (WCHAR*) new BYTE[cbSize + sizeof(WCHAR)];
if (pwszContent == NULL)
    return E_OUTOFMEMORY;

pStream->Seek(pos, STREAM_SEEK_SET, NULL);
SIZE_T cbRead;
pStream->Read(pwszContent, cbSize, &cbRead);
pwszContent[cbSize/sizeof(WCHAR)] = L'\0';

CZString czContent;
czContent.LoadWideString(pwszContent, cbSize);
wprintf(L"%S", czContent.GetString().c_str());
pStream->Seek(pos, STREAM_SEEK_SET, NULL);

if (hr == S_OK)
{
    typedef HRESULT (WINAPI *CreateXmlReaderFunc)(const IID & riid, void** ppvObject, IMalloc * pMalloc);
    CreateXmlReaderFunc _CreateXmlReaderFunc = (CreateXmlReaderFunc)GetProcAddress(m_hXMLLite, "CreateXmlReader");

    if (FAILED(hr = _CreateXmlReaderFunc(__uuidof(IXmlReader), (void**) &pReader, NULL)))
    {
        MessageBox(NULL, CStringHelper::Format(L"Error: GetProcAddress() failed to find 'CreateXmlReader' %d\n", GetLastError()).c_str(), L"Error", MB_OK);
        return -1;
    }

    pReader->SetInput(pStream);
}

while (S_OK == (hr = pReader->Read(&nodeType))) 
{
    switch (nodeType) 
    {
                    // parse xml here
    }
}
return 0;

1 Ответ

0 голосов
/ 11 января 2012

Ваша XML-строка неверна.Должно быть "=" между "версией" и "1.0".Во-вторых, строка использует UTF-16, а в заголовке указано, что это UTF-8.Измените UTF-8 на UTF-16 в заголовке или удалите атрибут кодирования.

LPWSTR pwszXMLString = 
L"<?xml version=\"1.0\" encoding=\"UTF-16\" ?>\r\n"

или

LPWSTR pwszXMLString = 
L"<?xml version=\"1.0\"?>\r\n"

работает.

...