当前位置:  开发笔记 > 编程语言 > 正文

MSXML选择节点不起作用

如何解决《MSXML选择节点不起作用》经验,为你挑选了1个好方法。

我正在开发一个自动化测试应用程序,目前我正在编写一个函数来比较两个XML文件之间的值,这些文件应该是相同的,但可能不是.以下是我正在尝试处理的XML示例:



  
    
      
        0
      
      
        1.000000
      
      
        0.000000
      
      
         
      
      
         
      
      
        N/A
      
      
         
      
      
         
      
    

(注意,可能有多个元素,其中包含多个元素.)

我想要的是提取两个文档的标签,然后比较它们的值.那部分我知道怎么做.问题在于提取本身.

由于我遇到了C++,我正在使用MSXML,并编写了一个包装器,允许我的应用程序抽象出实际的XML操作,以防我决定更改我的数据格式.

该包装器CSimpleXMLParser加载XML文档并将其"最高记录"设置为XML文档的document元素.(CRecord是一个抽象类,其CXMLRecord是其子类之一,它可以单独或按组访问子记录,还允许访问Record的"值"(对于子元素或属性的值,在CXMLRecord的情况下) .)CXMLRecord包含一个MSXML :: MSXMLDOMNodePtr和一个指向CSimpleXMLParser实例的指针.)包装器还包含返回子项的实用程序函数,CXMLRecord用它来返回子记录.

在我的代码中,我执行以下操作(尝试返回所有节点只是为了查看它是否有效):

CSimpleXMLParser parserReportData;
parserReportData.OpenXMLDocument(strPathToXML);
bool bGetChildrenSuccess = parserReportData.GetFirstRecord()->GetChildRecords(listpChildren, _T("subreport"));

这总是返回false.CXMLRecord :: GetChildRecords()的实现基本上是肉

MSXML2::IXMLDOMNodeListPtr pListChildren = m_pParser->SelectNodes(strPath, m_pXMLNode);

if (pListChildren->Getlength() == 0)
{
    return false;
}

for (long l = 0; l < pListChildren->Getlength(); ++l)
{
    listRecords.push_back(new CXMLRecord(pListChildren->Getitem(l), m_pParser));
}

return true;

CSimpleXMLParser :: SelectNodes()是:

MSXML2::IXMLDOMNodeListPtr CSimpleXMLParser::SelectNodes(LPCTSTR strXPathFilter, MSXML2::IXMLDOMNodePtr pXMLNode)
{
    return pXMLNode->selectNodes(_bstr_t(strXPathFilter));
}

运行时,顶级记录肯定正确地设置为元素.我可以用它做各种各样的事情,比如获取它的子节点(通过MSXML接口,而不是通过我的包装器)或它的名称等.我知道我的包装器可以工作,因为我在应用程序的其他地方使用它来解析一个XML配置文件,它完美无瑕.

我想也许我正在做一些错误的XPath查询表达式,但我能想到的每一个排列都没有带来任何乐趣.当我尝试处理这个XML文件时,MSXML::IXMLDOMNodeListPtr返回的IXMLDOMNodePtr::SelectNodes()值总是为0.

这真让我抓狂.



1> James Curran..:

我习惯用.NET的XmlDocument对象做这个,但我认为这里的效果是一样的:

如果XML文档包含命名空间 - 甚至是未命名的命名空间 - 那么Xpath查询也必须使用一个命名空间.因此,您必须将命名空间添加到XMLDoument中,您也可以在代码中给出一个名称,并在XPATH查询中包含前缀(xml文档和前缀之间的前缀不同并不重要) xpath,只要名称空间对其进行排序)

因此,当您使用XPath时/report/subreport/record/field/value,您实际上需要首先设置文档的命名空间:

  pXMLDoc->setProperty(_bstr_t("SelectionNamespaces"),
                       _bstr_t("xmlns:r="http://www.**.com/**"));

然后selectNodes()使用 /r:report/r:subreport/r:record/r:field/r:value

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有