Я работаю над автоматизированным тестовым приложением, и в настоящее время я нахожусь в процессе написания функции, которая сравнивает значения между двумя XML-файлами, которые должны быть идентичными, но могут и не быть. Вот образец XML Я пытаюсь процесс:MSXML Выбор узлов не работает
<?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>
(Примечание может быть несколько <subreport>
элементов и в тех, несколько <record>
элементов.)
То, что я хотел бы, чтобы извлечь теги <value>
двух документов, а затем сравнивают их значения. Эта часть, которую я знаю, как делать. Проблема заключается в самой добыче.
Поскольку я застрял на C++, я использую MSXML и написал оболочку, чтобы позволить моему приложению абстрагироваться от фактических манипуляций с XML, если я когда-либо решил изменить свой формат данных.
Эта обертка, CSimpleXMLParser, загружает XML-документ и устанавливает его «верхнюю запись» в элемент документа XML-документа. (CRecord является абстрактным классом с CXMLRecord одним из своих подклассов и который обеспечивает доступ к дочерним записям синхронно или по группам, а также позволяет получить доступ к «значению» записи (значения для дочерних элементов или атрибутов, в случае CXMLRecord .) CXMLRecord содержит MSXML :: MSXMLDOMNodePtr и указатель на экземпляр CSimpleXMLParser.) В оболочке также содержатся служебные функции для возвращаемых детей, которые CXMLRecord использует для возврата своих дочерних записей.
В моем коде, я следующее (пытается вернуть все <subreport>
узлы просто чтобы увидеть, если он работает):
CSimpleXMLParser parserReportData;
parserReportData.OpenXMLDocument(strPathToXML);
bool bGetChildrenSuccess = parserReportData.GetFirstRecord()->GetChildRecords(listpChildren, _T("subreport"));
Это всегда возвращается ложь. Мясо реализации 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));
}
При запуске, верхняя запись определенно быть установлен в <report>
элемент правильно. Я могу делать с ним всевозможные вещи, например, получать свои дочерние узлы (через интерфейс MSXML, а не через мою оболочку) или его имя и т. Д. Я знаю, что моя обертка может работать, потому что я использую ее в другом месте приложения для синтаксического анализа файла конфигурации XML, и это работает безупречно.
Я подумал, что, возможно, я делал что-то неправильно с выражением запроса XPath, но каждая перестановка, о которой я могла думать, не дает радости. MSXML::IXMLDOMNodeListPtr
, возвращенный IXMLDOMNodePtr::SelectNodes()
, всегда имеет длину 0, когда я пытаюсь разобраться с этим XML-файлом.
Это сводит меня с ума.
Замечу, что если я заменил XML-документ здесь одним из моих файлов конфигурации и попробуйте выбрать его узлы, он отлично работает. Есть ли что-то неправильное в этом XML-файле? – 2008-11-12 17:48:32