Eu estou trabalhando em um aplicativo de teste automatizado, e estou atualmente no processo de escrever uma função que compara valores entre dois arquivos XML que devem ser idênticos, mas pode não ser. Aqui está uma amostra do XML Eu estou tentando processo:
<?xml version=1.0 encoding=utf-8?>
<report xmlns=http://www.**.com/**>
<subreport name=RBDReport>
<record rowNumber=1>
<field name=Time>
<value>0</value>
</field>
<field name=Reliability>
<value>1.000000</value>
</field>
<field name=Unreliability>
<value>0.000000</value>
</field>
<field name=Availability>
<value> </value>
</field>
<field name=Unavailability>
<value> </value>
</field>
<field name=Failure Rate>
<value>N/A</value>
</field>
<field name=Number of Failures>
<value> </value>
</field>
<field name=Total Downtime>
<value> </value>
</field>
</record>
(Nota pode haver múltiplos <subreport>elementos e aqueles dentro de, vários <record>elementos.)
O que eu gostaria é extrair as <value>marcas de dois documentos e então comparar seus valores. Essa parte eu sei como fazer. O problema é a própria extração.
Desde que eu estou preso em C ++, eu estou usando MSXML, e ter escrito um invólucro para permitir que meu aplicativo para abstrair a manipulação XML real, no caso de eu decidir que quer mudar o meu formato de dados.
Esse invólucro, CSimpleXMLParser, carrega um documento XML e define seu registro superior para o elemento do documento do documento XML. (CRecord sendo uma classe abstrata com CXMLRecord uma de suas subclasses, e que dá acesso a registros filho individualmente ou por grupo, e também permitindo o acesso ao valor do registro (valores para elementos filhos ou atributos, no caso de CXMLRecord .) a CXMLRecord contém um MSXML :: MSXMLDOMNodePtr e um ponteiro para uma instância de um CSimpleXMLParser.) o invólucro também contém funções de utilidade para as crianças que retornam, que o CXMLRecord usa para retornar seus registros filho.
No meu código, eu faço o seguinte (tentando devolver todos <subreport>nós só para ver se ele funciona):
CSimpleXMLParser parserReportData;
parserReportData.OpenXMLDocument(strPathToXML);
bool bGetChildrenSuccess = parserReportData.GetFirstRecord()->GetChildRecords(listpChildren, _T(subreport));
Este é sempre retornar false. A carne da implementação do CXMLRecord :: GetChildRecords () é, basicamente,
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;
E CSimpleXMLParser :: SelectNodes () é:
MSXML2::IXMLDOMNodeListPtr CSimpleXMLParser::SelectNodes(LPCTSTR strXPathFilter, MSXML2::IXMLDOMNodePtr pXMLNode)
{
return pXMLNode->selectNodes(_bstr_t(strXPathFilter));
}
Quando executado, o registro superior definitivamente está sendo definido para o <report>elemento corretamente. Eu posso fazer todos os tipos de coisas com ele, como a obtenção de seus nós filho (através da interface do MSXML, não através do meu invólucro) ou seu nome, etc. Eu sei que o meu invólucro pode trabalhar, porque eu usá-lo em outras partes do aplicativo para análise um arquivo de configuração XML, e que funciona perfeitamente.
Eu pensei que talvez eu estava fazendo algo defeituoso com a expressão de consulta XPath, mas todas as permutações que eu poderia pensar não dá nenhuma alegria. A MSXML::IXMLDOMNodeListPtrdevolvido pelo IXMLDOMNodePtr::SelectNodes()é sempre de comprimento 0, quando eu tentar lidar com esse arquivo XML.
Isto está me enlouquecendo.













