VC++でのXMLの読み込み

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たにさん

VC++でのXMLの読み込み

#1

投稿記事 by たにさん » 18年前

はじめまして!今、学校の課題でVisual C++.NET 2003でプログラムを書いています。

VC++にはXMLに関するクラスやメソッドが沢山用意されているらしいですが、
それについて質問があります(基本的なことでゴメンナサイ…;;

<doc>
  <会社 名前=○○株式会社>
    <社長>Aさん</社長>
    <部長>Bさん</部長>
    <課長>Cさん</課長>
  </会社>
  <会社 名前=有限式会社××>
    <社長>Dさん</社長>
    <部長>Eさん</部長>
    <課長>Fさん</課長>
  </会社>
</doc>

このようなXMLがあったとして、このXMLをファイルから読み込んで、
「会社」「社長」「部長」「課長」という名前の配列にそれぞれ格納したいです。

たとえば、「社長」には、AさんとDさんが入るようにしたいです。

参考書片手に調べてみたんですが、
配列を作り終えた段階で行き詰ってしまいました…。

具体的には、上から一列ずつ読んで行って、
最初に出てきたのが「<社長>Aさん</社長>」だったら、それを「社長」の配列に格納し、
次が「<部長>Bさん</部長>」だったら、「部長」配列に…という具合にしたいです。
たまに、部長が二人いたりする会社もあることを考えたいです。

つたない文章で申し訳ありませんが、
お分かりになる方がいたら、どうぞ宜しくお願いしますm(_ _)m

YuO

Re:VC++でのXMLの読み込み

#2

投稿記事 by YuO » 18年前

IXMLDOMDocument::getElementByTagName (MSXMLの場合)
DOMDocument::getElementByTagName (Xerces-C++の場合)
System::Xml::XmlDcoument::GetElementByTagName (MC++/System.Xmlの場合)

あたりを使えば,要素名が"社長"だとか,"部長"だとかでとってこれます。

たにさん

Re:VC++でのXMLの読み込み

#3

投稿記事 by たにさん » 18年前

ありがとうございます!
調べてみたところ、GetElementByTagName("社長")などのようにして
要素を取ってくるメソッドのようですね。
それを使って、if文などで条件指定は出来るのでしょうか?

if(もし要素名が"○○"だったら)
{
配列"○○"に格納
}

のようにしたいのですが…続けての質問で申し訳ありません。

YuO

Re:VC++でのXMLの読み込み

#4

投稿記事 by YuO » 18年前

まずは修正から。
>> IXMLDOMDocument::getElementByTagName (MSXMLの場合)
>> DOMDocument::getElementByTagName (Xerces-C++の場合)
>> System::Xml::XmlDcoument::GetElementByTagName (MC++/System.Xmlの場合)

IXMLDOMDocument::getElementsByTagName (MSXMLの場合)
DOMDocument::getElementsByTagName (Xerces-C++の場合)
System::Xml::XmlDcoument::GetElementsByTagName (MC++/System.Xmlの場合)
と,(当然ながら)全部複数形です。

> それを使って、if文などで条件指定は出来るのでしょうか?
したければできますが,する必要はないでしょう。

お試し @ VC++2005 with /clr:pure option
#using "system.xml.dll"

using namespace System;
using namespace System::Xml;

void Write (XmlDocument^ doc, String^ target)
{
    XmlNodeList^ list = doc->GetElementsByTagName(target);

    Console::WriteLine(target);
    for each (XmlElement^ element in list)
    {
        Console::WriteLine(L"\t{0}", element->InnerText);
    }
}

int main ()
{
    XmlDocument^ doc = gcnew XmlDocument();
    doc->Load(L"test.xml");

    Write(doc, L"社長");
    Write(doc, L"部長");

    return 0;
}
出力
社長
        Aさん
        Dさん
部長
        Bさん
        Eさん
一個ずつ処理したければ,要素をたどる方法になると思いますが……。
# それならDOMではなくSAXの方が効率が良さそうです。

たにさん

Re:VC++でのXMLの読み込み

#5

投稿記事 by たにさん » 18年前

遅れて申し訳ありません。
お返事頂いてから、色々と試してみていたのですが、

for each (XmlElement^ element in list)
{
Console::WriteLine(L"\t{0}", element->InnerText);
}

のあたりが上手く動きません…(Debug::WriteLine()でやってます)

^ はポインタ…なのでしょうか?これを自分の環境のポインタ * に変えたりしても動きません…(汗
あと、elementの宣言はどこで行えば良いのでしょうか?

何度も質問して本当に申し訳ないです↓↓

たにさん

書いてみたソース

#6

投稿記事 by たにさん » 18年前

自分なりに、YuOさんやVisual Studio 2003.NETのヘルプを元に作ってみた
XMLの読み込み部分を一応書いてみます。

private: bool LoadXmlFile(String *path)
{
XmlDocument *doc = new XmlDocument();
doc->Load(path);

XmlElement *root = doc->DocumentElement;
XmlNodeList *alist = doc->GetElementsByTagName("agent");
IEnumerator *ienum = alist->GetEnumerator();

while(ienum->MoveNext()) {
XmlNode *agenta = __try_cast<XmlNode*>(ienum->Current);
Debug::WriteLine(agenta);
}

return true;
}

//XML読み込みボタン
private: System::Void menuItem5_Click(System::Object * sender, System::EventArgs * e)
{
Debug::WriteLine("XMLオープン");
OpenFileDialog *dlg = new OpenFileDialog();
dlg->Filter = "XML形式(*.xml)|*.xml|すべてのファイル(*.*)|*.*";
if(dlg->ShowDialog() != DialogResult::OK)
{
return;
}
LoadXmlFile(dlg->FileName);
}

下のXML読み込みボタンを押すと、上のLoadXmlFile()の処理を読み込むように作ってみました。

コンパイルは通り、ファイル読み込みのダイアログを呼び出すまでは正常に進むのですが、
ファイル名を指定して「開く」を押すと下のように表示されてエラーが出ます…。

-------------------------------------------------------------------------------------
System.Xml.XmlException' のハンドルされていない例外が system.xml.dll で発生しました。
追加情報 : システム エラーです。
-------------------------------------------------------------------------------------

以前挙げた「社長」や「部長」などではなく、このプログラムでは「agent」などの要素名です。
長くなってしまい申し訳ありませんが、宜しくお願いしますm(_ _)m

閉鎖

“C言語何でも質問掲示板” へ戻る