MSXML6解析XML时将注释识别为子节点的原因咨询
Why MSXML6 Treats XML Comments as Child Nodes Instead of Ignoring Them?
这是个很容易踩坑的XML解析细节,我来给你拆解清楚:
首先得纠正一个常见误解:XML解析器并不会默认忽略注释——根据XML规范,注释是文档的合法组成部分,解析器可以选择保留或忽略它们,而MSXML6的默认行为就是把注释作为DOM树里的正式节点(节点类型为NODE_COMMENT)保留下来。
你之前的代码能正常处理旧格式XML,大概率是因为旧格式里的注释位置不在你读取的首个节点的子节点列表里,或者代码遍历节点时刚好没碰到;而新格式的注释刚好出现在你要读取的目标节点前面,导致代码拿到的第一个“子节点”是注释节点,你的逻辑识别不了这个类型,就触发了退出机制。
如果不想通过删除注释解决,其实可以在代码里做两个优化:
- 遍历DOM节点时,主动判断节点类型,碰到
NODE_COMMENT就直接跳过,继续处理下一个节点 - 配置MSXML的解析选项,让它忽略注释:可以通过
IXMLDOMDocument2::setProperty方法调整解析规则,不过最简单的还是在遍历的时候跳过注释节点
举个C++里的简单示例,遍历子节点时跳过注释:
IXMLDOMNodeList* pNodes = NULL; pParentNode->get_childNodes(&pNodes); long nodeCount = 0; pNodes->get_length(&nodeCount); for (long i = 0; i < nodeCount; i++) { IXMLDOMNode* pNode = NULL; pNodes->get_item(i, &pNode); VARIANT_BOOL isComment = VARIANT_FALSE; pNode->get_nodeTypeString(L"comment", &isComment); if (isComment) { pNode->Release(); continue; } // 处理正常节点的业务逻辑 pNode->Release(); } pNodes->Release();
这样即使XML里保留注释,也不会影响你的业务逻辑啦。
内容的提问来源于stack exchange,提问作者Mark Gould
相关产品推荐
相关产品推荐

