【问题标题】:How can I determine why a call to IXMLDOMDocument::load() fails?如何确定调用 IXMLDOMDocument::load() 失败的原因?
【发布时间】:2011-01-09 19:05:25
【问题描述】:

我正在尝试调试我的代码中出现的 XML 解析问题。我已将其隔离为以下代码 sn-p:

HRESULT
CXmlDocument::Load(IStream* Stream)
{
    CComVariant xmlSource(static_cast<IUnknown*>(Stream));
    VARIANT_BOOL isSuccessful;
  * HRESULT hr = m_pXmlDoc->load(xmlSource, &isSuccessful);
    return (hr == S_FALSE) ? E_FAIL : hr;
}

注意: m_pXmlDoc 的类型是 CComPtr&lt;IXMLDOMDocument&gt;

似乎对IXMLDOMDocument::load()(标有*)的调用失败 - IOW,它正在返回S_FALSE

我无法进入 load() 来确定它失败的原因,因为它是一个 COM 调用。

此方法的MSDN page 似乎并没有提供很多见解。

我有一些预感:

  • XML 格式不正确
  • XML 文件太大(约 120MB)
  • 这是与内存相关的问题(失败时进程大小达到 > 2GB)
    • 注意: 已设置注册表项以允许进程大小如此之大,因为 WinXP AFAIK 的最大有效进程大小为 2GB。

关于为什么此调用可能会失败的任何想法?

【问题讨论】:

标签: c++ xml com


【解决方案1】:

以下代码将从 DOM 中获取特定的解析器错误及其在源 XML 中的位置。

CComPtr<IXMLDOMParseError> pError;
CComBSTR sReason, sSource;
long nLine = 0, nColumn = 0;

m_pXmlDoc->get_parseError(&pError);
if(pError)
{
    pError->get_reason(&sReason);
    pError->get_srcText(&sSource);
    pError->get_line(&nLine);
    pError->get_linepos(&nColumn);
}

sReason 将填充错误消息。 sSource 将在 XML 中包含错误的源代码行。 nLinenColumn 应该设置为错误的行号和列,尽管在实践中这两个设置并不总是可靠的(iirc,这尤其适用于验证错误,而不是解析器/格式正确的错误)。

【讨论】:

  • 感谢您的建议 - 我已经提取了错误,并且每次运行它似乎都不同。这表明我遇到了内存问题,而不是格式错误的 XML。我对此提出了一个新问题:stackoverflow.com/questions/2152492/…
【解决方案2】:

如果 XML 文件由另一个 Task 或 Process 打开 Load() 方法 无法加载文件,但没有说明加载失败。 我认为这种行为是一个错误。

所以你必须检查属性 documentElement - 如果它是 null,load() 也失败了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 2020-08-28
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    相关资源
    最近更新 更多