所有
这是我的代码
//declare string pointer
BSTR markup;
//initialize markup to some well formed XML <-
//declare and initialize XML Document
MSXML2::IXMLDOMDocument2Ptr pXMLDoc;
HRESULT hr;
hr = pXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));
pXMLDoc->async = VARIANT_FALSE;
pXMLDoc->validateOnParse = VARIANT_TRUE;
pXMLDoc->preserveWhiteSpace = VARIANT_TRUE;
//load markup into XML document
vtBoolResult = pXMLDoc->loadXML(markup);
//do some changes to the XML file<-
//get back string from XML doc
markup = pXMLDoc->Getxml(); //<-- this retrieves RUBBISH
此时我的字符串被破坏了(开头只有几个汉字然后是垃圾)。看起来像编码问题。
我也尝试了以下内容:
_bstr_t superMarkup = _bstr_t(markup);
//did my stuff
superMarkup = pXMLDoc->Getxml();
markup = superMarkup;
但我仍然得到相同的结果。
即使我在不更改xml文档中的任何内容的情况下调用GetXML(),我仍然会得到垃圾。
此时如果我尝试将损坏的指针分配给另一个指针,它将抛出一个错误:
尝试恢复写保护 记忆。这通常是一个迹象 其他内存已损坏。
有什么建议吗?
EDIT1:
我发现这与XML字符串的大小有关。 如果它发生在给定的XML字符串上并且我减小了大小(保持相同的模式)它将正常工作。看起来像MSXML2 :: DOMDocument40有大小限制? 详细地说,如果我有超过16407个字符,就会发生这种情况。我还有一个GetXML将检索RUBBISH - 如果它是&lt; = 16407一切正常。
EDIT2:
罗迪是对的 - 我错过了_bstr_t
是一个班级......
敲响铃声?
干杯
答案 0 :(得分:4)
尝试替换
BSTR Markup;
带
bstr_t Markup;
BSTR几乎是一个愚蠢的指针,我认为GetXML()的返回结果正在转换为临时值,然后在你看到它时就会被破坏。 bstr_t用一些智能指针的优点包装它......
注意:你的“SuperMarkup”事情并不符合我的建议。同样, BSTR只是一个指针,并且不“拥有”它所指向的内容。另一方面,bstr_t。我认为你的GetXML()函数正在返回一个bstr_t,然后当它超出范围时被删除,让你的BSTR指向不再有效的内存。
答案 1 :(得分:1)
好的,我认为帕特里克是对的。我拿了你的代码,做了一个名为getxmltest的快速ATL EXE项目。 我在#include指令
之后添加了这一行#import "MSXML3.DLL"
删除了注册组件的post-build事件,因为我不想暴露exe中的任何组件,但只有所有ATL头文件和libs已经引用,并将以下代码添加到_tWinMain
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
LPTSTR /*lpCmdLine*/, int nShowCmd)
{
CoInitialize(NULL);
{
//declare string pointer
_bstr_t markup;
//initialize markup to some well formed XML <-
//declare and initialize XML Document
MSXML2::IXMLDOMDocument2Ptr pXMLDoc;
HRESULT hr = pXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument));
pXMLDoc->async = VARIANT_FALSE;
pXMLDoc->validateOnParse = VARIANT_TRUE;
pXMLDoc->preserveWhiteSpace = VARIANT_TRUE;
//load markup into XML document
VARIANT_BOOL vtBoolResult = pXMLDoc->loadXML(L"<XML></XML>");
//do some changes to the XML file<-
//get back string from XML doc
markup = pXMLDoc->Getxml(); //<-- this retrieves RUBBISH (not anymore...)
ATLTRACE("%S", (BSTR)markup.GetBSTR());
}
CoUninitialize();
return _AtlModule.WinMain(nShowCmd);
}
得到的跟踪线如下......
'getxmltest.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.6001.18000_none_5cdbaa5a083979cc\comctl32.dll'
<XML></XML>
'getxmltest.exe': Unloaded 'C:\Windows\SysWOW64\msxml3.dll'
The program '[6040] getxmltest.exe: Native' has exited with code 0 (0x0).
我们可以看到最初输入的字符串.. 我没有在代码中添加任何逻辑,因为我虽然这足以在使用MSXML引擎处理后显示生成的xml。显然,您可以使用此代码进行更多测试,看看接下来会发生什么。
答案 2 :(得分:1)
我不熟悉这个特定的 xml库,但是:
这里要注意的是原始问题在检索结果时覆盖了变量'markup'。许多XML解析器返回指向初始输入(即标记)的指针,因此当您用输出替换它时,您还会删除XML解析器的输入。
此过程似乎可能会使您刚收到的字符串无效。你会注意到EugenioMiró在他的例子中没有犯这个错误,因为他分配了一个不同的变量来保存输入(pXMLDoc)。
您可能想做的快速测试是更改
//get back string from XML doc
markup = pXMLDoc->Getxml(); //<-- this retrieves RUBBISH
到
//get back string from XML doc
BSTR output = pXMLDoc->Getxml(); //<-- perhaps this doesn't
看看是否有所作为。
答案 3 :(得分:1)
这是我之前编写的代码,稍加修改,增加了20000个'子元素':)它运行良好。
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
LPTSTR /*lpCmdLine*/, int nShowCmd)
{
CoInitialize(NULL);
{
//declare string pointer
_bstr_t markup;
//initialize markup to some well formed XML <-
//declare and initialize XML Document
try {
MSXML2::IXMLDOMDocument2Ptr pXMLDoc;
HRESULT hr = pXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument));
pXMLDoc->async = VARIANT_FALSE;
pXMLDoc->validateOnParse = VARIANT_TRUE;
pXMLDoc->preserveWhiteSpace = VARIANT_TRUE;
//load markup into XML document
VARIANT_BOOL vtBoolResult = pXMLDoc->loadXML(L"<XML></XML>");
for (int i = 0; i < 20000; i++) {
MSXML2::IXMLDOMNodePtr node = pXMLDoc->createNode(_variant_t("element"), _bstr_t("child"), _bstr_t(""));
if (node)
pXMLDoc->documentElement->appendChild(node);
}
//do some changes to the XML file<-
//get back string from XML doc
markup = pXMLDoc->Getxml(); //<-- th
ATLTRACE("XML lenght = %d, xml=%S\n", markup.length(), (BSTR)markup.GetBSTR());
} catch(_com_error e) {
ATLTRACE("error = %S\n", (BSTR)e.ErrorMessage());
}
}
CoUninitialize();
return _AtlModule.WinMain(nShowCmd);
}
这会在调试器中生成1024输出行,但如果您愿意,这可以轻松地将xml打印到stdoutput。 这是我到目前为止的输出
'getxmltest.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.6001.18000_none_5cdbaa5a083979cc\comctl32.dll'
XML lenght = 160013, xml=<XML><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><child/><'getxmltest.exe': Unloaded 'C:\Windows\SysWOW64\msxml3.dll'
The program '[4884] getxmltest.exe: Native' has exited with code 0 (0x0).