私は自動テストアプリに取り組んでおり、現在、同一である必要があるがそうではない可能性がある2つのXMLファイル間の値を比較する関数を作成中です。処理しようとしている XML のサンプルを次に示します。
<?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>
、2 つのドキュメントのタグを抽出し、それらの値を比較することです。その部分は私が行う方法を知っています。問題は抽出そのものです。
私は C++ で立ち往生しているので、MSXML を使用しており、データ形式を変更することにした場合に備えて、アプリが実際の XML 操作を抽象化できるようにするラッパーを作成しました。
そのラッパーである CSimpleXMLParser は、XML ドキュメントをロードし、その「トップ レコード」を XML ドキュメントのドキュメント要素に設定します。(CRecord は、そのサブクラスの 1 つである CXMLRecord を持つ抽象クラスであり、子レコードへの単独またはグループによるアクセスを提供し、Record の「値」へのアクセスも許可します (CXMLRecord の場合、子要素または属性の値) .) CXMLRecord には、MSXML::MSXMLDOMNodePtr と、CSimpleXMLParser のインスタンスへのポインターが含まれています。) ラッパーには、CXMLRecord が子レコードを返すために使用する、子を返すためのユーティリティ関数も含まれています。
私のコードでは、次のことを行います (<subreport>
機能するかどうかを確認するためだけにすべてのノードを返そうとします)。
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));
}
実行すると、トップ レコードが確実に<report>
要素に適切に設定されます。子ノードの取得 (ラッパー経由ではなく、MSXML インターフェイス経由) やその名前など、あらゆる種類の処理を実行できます。アプリの別の場所で解析のために使用しているため、ラッパーが機能することはわかっています。 XML 構成ファイルであり、問題なく動作します。
XPath クエリ式で何か間違ったことをしているのかもしれないと思いましたが、考えられるすべての順列は喜びを与えません。このXML ファイルを処理しようとすると、MSXML::IXMLDOMNodeListPtr
返されるIXMLDOMNodePtr::SelectNodes()
は常に長さ 0 です。
これは私を夢中にさせています。