![]() ![]() ![]()
|
BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア : SophiaFramework UNIVERSE 5.0 |
例 20.2. 解析対象の XML 文書 ( file.xml )
<fruit> <name>apple</name> <size>XS</size> <color>red</color> </fruit>
例 20.3. 要素の取得
SFCError error; // エラー値 SFXXMLDOMParser parser; // DOM パーサー SFXAnsiString resultString; // ノードの名前を格納する変数 // file.xml に保存した XML 文書を解析する if ((error = parser.Parse("/file.xml")) == SFERR_NO_ERROR) { // DOM ツリーのルート ノードを取得する SFXXMLDocumentPtr root = parser.GetDocument(); // ルート ノードの最初の子ノード ( "fruit" ノード ) を取得する SFXXMLNodePtr child = root->GetFirstChild(); // "fruit" ノードの名前を取得する ( resultString は "fruit" になる ) resultString = child->GetNodeName(); // "fruit" ノードのノード タイプを取得する ( type は ELEMENT_NODE になる) SFXXMLNode::NodeType type = child->GetNodeType(); // "fruit" ノードの最初の子ノードを取得する SFXXMLNodePtr node = child->GetFirstChild(); // ノードの名前を取得する ( resultString は "name" になる ) resultString = node->GetNodeName(); // ノード タイプを取得する ( type は ELEMENT_NODE になる ) type = node->GetNodeType(); // "name" ノードの最初の子ノードを取得する SFXXMLNodePtr textNode = node->GetFirstChild(); // ノードの名前を取得する ( resultString は "apple" になる ) resultString = textNode->GetNodeValue(); // ノード タイプを取得する (type は TEXT_NODE になる) type = textNode->GetNodeType(); // "name" ノードの、次の兄弟ノードを取得する node = node->GetNextSibling(); // ノードの名前を取得する ( resultString は "size" になる ) resultString = node->GetNodeName(); // ノード タイプを取得する ( type は ELEMENT_NODE になる ) type = node->GetNodeType(); }
![]() |
注意 |
|---|---|
| ルート ノードは、SFXXMLDOMParser::GetDocument 関数、 子ノードは SFXXMLNode::GetFirstChild 関数を使って取得します。 | |
例 20.4. 複数ノードの取得
SFCError error; // エラー値 SFXXMLDOMParser parser; // DOM パーサー SFXAnsiString resultString; // ノードの名前を格納する変数 // file.xml に保存した XML 文書を解析する if ((error = parser.Parse("/file.xml")) == SFERR_NO_ERROR) { // DOM ツリーのルート ノードを取得する SFXXMLDocumentPtr root = parser.GetDocument(); // ルート ノードの最初の子ノード ( "fruit" ノード ) を取得する SFXXMLNodePtr child = root->GetFirstChild(); // "fruit" ノードのすべての子ノードを取得する // SFXXMLNode::DOMNodeListPtr は SFXList<SFXXMLNodePtr> と同じ SFXXMLNode::DOMNodeListPtr nodeList = child->GetChildNodes(); // イテレータを取得する SFXXMLNode::DOMNodeList::Iterator itor = nodeList->GetFirstIterator(); while (itor.HasNext()) { // 次のノードがあるかぎり繰り返す // "name" ノード、"size" ノード、"color" ノードの順に取得できる SFXXMLNodePtr node = itor.GetNext(); // ノードの名前を取得する resultString = node->GetNodeName(); // ノードのテキストを取得する ( "name" ノードの場合は "apple"、"size" ノードの場合は "XS" ) resultString = node->GetText(); } // "color" というタグ名を持つすべての Element ノードを取得する nodeList = static_cast<SFXXMLElementPtr>(child)->GetElementsByTagName("color"); // イテレータを取得する itor = nodeList->GetFirstIterator(); // 各 Element ノードに対する処理 while (itor.HasNext()) { // 次の Element ノードを取得する SFXXMLNodePtr node = itor.GetNext(); // ... } }
![]() |
注意 |
|---|---|
| すべての子ノードを取得するには、SFXXMLNode::GetChildNodes 関数を使います。 | |
例 20.5. 解析対象の XML 文書 ( file.xml )
<fruits>
<fruit>
<name>apple</name>
<size>XS</size>
<color>red</color>
</fruit>
<fruit>
<name>banana</name>
<size>S</size>
<color>yellow</color>
</fruit>
<fruit>
<name>melon</name>
<size>XS</size>
<color>green</color>
</fruit>
</fruits>
例 20.6. 各ノードに対する処理
SFCError error; // エラー値 SFXXMLDOMParser parser; // DOM パーサー // file.xml に保存した XML 文書を解析する if ((error = parser.Parse("/file.xml")) == SFERR_NO_ERROR) { // DOM ツリーのルート ノードを取得する SFXXMLDocumentPtr root = parser.GetDocument(); // ルート ノードの最初の子ノード ( "fruits" ノード ) を取得する SFXXMLNodePtr child = root->GetFirstChild(); // "fruits" ノードの最初の子ノード( "fruit" ノード)を取得する SFXXMLNodePtr node = child->GetFirstChild(); // "fruit" ノードの各子ノードに対する処理 while (node != null) { // 最初の子ノード( "name" ノード)を取得する SFXXMLNodePtr nameNode = node->GetFirstChild(); // ノードのテキストを取得する SFXAnsiString resultString = nameNode->GetText(); // 次の兄弟ノードを取得する node = node->GetNextSibling(); } }
![]() |
注意 |
|---|---|
| 兄弟ノードは while ループ内で SFXXMLNode::GetNextSibling 関数を使って順次取得します。 | |
例 20.7. 解析対象の XML 文書 ( file.xml )
<fruit>
<name language="english" code="ascii">apple</name>
<size>XS</size>
<color>red</color>
</fruit>
例 20.8. 属性の取得
SFCError error; // エラー値 SFXXMLDOMParser parser; // DOM パーサー SFXAnsiString resultString; // 属性の値を格納する変数 // file.xml に保存した XML 文書を解析する if ((error = parser.Parse("/file.xml")) == SFERR_NO_ERROR) { // DOM ツリーのルート ノードを取得する SFXXMLDocumentPtr root = parser.GetDocument(); // ルート ノードの最初の子ノード ( "fruit" ノード ) を取得する SFXXMLNodePtr child = root->GetFirstChild(); // "fruit" ノードの最初の子ノード ( "name" ノード ) を取得する child = child->GetFirstChild(); // child ノードの名前が "name" のとき if (SFXAnsiString("name").Equals(child->GetNodeName())) { // Attribute ノードは Element ノードから取得するので、キャストの必要がある SFXXMLElementPtr element = static_cast<SFXXMLElementPtr>(child); // "language" という名前の Attribute ノードの値を取得する // resultString は "english" になる resultString = element->GetAttribute("language"); // "language" という名前の Attribute ノード を取得する SFXXMLAttributePtr attr = element->GetAttributeNode("language"); // Attribute ノードの値(属性値)を取得する resultString = attr->GetNodeValue(); // すべての Attribute ノード を取得する SFXXMLNode::DOMNamedNodeMapPtr nodeMap = element->GetAttributes(); // DOMNamedNodeMap から名前を指定して Attribute ノード を取得する attr = static_cast<SFXXMLAttributePtr>(nodeMap->GetNamedItem("code")); // Attribute ノードの値(属性値)を取得する resultString = attr->GetNodeValue(); } }
![]() |
注意 |
|---|---|
| Attribute ノードの値(属性値)を取得するには SFXXMLElement::GetAttribute 関数を使います。 | |
XML 文書の作成
XML 文書は SFXXMLDocument クラスや SFXXMLElement クラスを使って以下の手順で作成します。
例 20.9. XML 文書の作成
SFCError error; // エラー値 // document ノード(Document ノード: DOM ツリーのルート ノード)を作成する SFXXMLDocument document; // document ノードに XML 文書のバージョンを設定する document.SetVersion("1.0"); // collection ノード(タグ名が "COLLECTION" の Element ノード)を作成する SFXXMLElementPtr collection = document.CreateElement("COLLECTION"); if (collection == null) { return; } // document ノードに collection ノードを追加する error = document.AppendChild(SFXXMLNodePtr(collection)); if (error != SFERR_NO_ERROR) { return; } // collection ノードに属性を追加する collection->SetAttribute("xmlns:dt", "urn:schemas-microsoft-com:datatypes"); // date ノード(タグ名が "DATE" の Element ノード)を作成する SFXXMLElementPtr date = document.CreateElement("DATE"); if (date == null) { return; } // date ノードに属性を追加する date->SetAttribute("dt:dt", "datetime"); // date ノードにテキスト情報を追加する error = date->AppendChild(SFXXMLNodePtr( document.CreateTextNode("1998-10-13T15:56:00"))); if (error != SFERR_NO_ERROR) { return; } // collection ノードに date ノードを追加する error = collection->AppendChild(SFXXMLNodePtr(date)); if (error != SFERR_NO_ERROR) { return; } // book ノード(タグ名が "BOOK" の Element ノード)を作成する SFXXMLElementPtr book = document.CreateElement("BOOK"); if (book == null) { return; } // collection ノードに book ノードを追加する error = collection->AppendChild(SFXXMLNodePtr(book)); if (error != SFERR_NO_ERROR) { return; } // "<TITLE>Cosmos</TITLE>" を作成する element = document.CreateElement("TITLE"); if (element == null) { return; } error = element->AppendChild(SFXXMLNodePtr(document.CreateTextNode("Cosmos"))); if (error != SFERR_NO_ERROR) { return; } error = book->AppendChild(SFXXMLNodePtr(element)); if (error != SFERR_NO_ERROR) { return; } // "<AUTHOR>Carl Sagan</AUTHOR>" を作成する element = document.CreateElement("AUTHOR"); if (element == null) { return; } error = element->AppendChild(SFXXMLNodePtr(document.CreateTextNode("Carl Sagan"))); if (error != SFERR_NO_ERROR) { return; } error = book->AppendChild(SFXXMLNodePtr(element)); if (error != SFERR_NO_ERROR) { return; } // "<PUBLISHER>Ballantine Books</PUBLISHER>" を作成する element = document.CreateElement("PUBLISHER"); if (element == null) { return; } error = element->AppendChild(SFXXMLNodePtr(document.CreateTextNode("Ballantine Books"))); if (error != SFERR_NO_ERROR) { return; } error = book->AppendChild(SFXXMLNodePtr(element)); if (error != SFERR_NO_ERROR) { return; } // XML 文書を保存する error = document.Save("book.xml"); if (error != SFERR_NO_ERROR) { return; }
例 20.10. 実行結果
<?xml version='1.0'?>
<COLLECTION
xmlns:dt="urn:schemas-microsoft-com:datatypes">
<DATE dt:dt="datetime">1998-10-13T15:56:00</DATE>
<BOOK>
<TITLE>Cosmos</TITLE>
<AUTHOR>Carl Sagan</AUTHOR>
<PUBLISHER>Ballantine Books</PUBLISHER>
</BOOK>
</COLLECTION>
![]() |
エミュレーター使用時の注意 |
|---|---|
エミュレーターのファイル システムの容量がオーバーした場合は、"book.xml" は生成されません。 | |
SAX パーサー (SFXXMLSAXParser) はイベント駆動型の XML パーサーです。SAX パーサーは XML 文書を先頭から解析していき、タグや属性が現れるたびにイベントを発生させます。ユーザーはイベント発生時に実行させたい関数 (ハンドラ) をあらかじめ SAX パーサーに登録しておきます。
SFXXMLDefaultHandler クラスを継承するハンドラ クラスを定義して、SAX パーサーに登録します。
例 20.11. 解析対象の XML 文書 ( file.xml )
<fruit>
<name language="english" code="ascii">apple</name>
<size>XS</size>
<color>red</color>
</fruit>
例 20.12. ハンドラ クラスの定義と実装
// ハンドラ クラス class MyXMLHandler : public SFXXMLDefaultHandler { public: explicit MyXMLHandler(Void); virtual ~MyXMLHandler(Void); // 各ハンドラの宣言 // データの内容を取得するハンドラ virtual Void Characters(SFXAnsiStringConstRef string, BoolConst cdataSection = true); virtual Void EndDocument(Void); virtual Void EndElement(SFXAnsiStringConstRef uri = SFXAnsiString::EmptyInstance(), SFXAnsiStringConstRef localname = SFXAnsiString::EmptyInstance(), SFXAnsiStringConstRef qname = SFXAnsiString::EmptyInstance()); virtual Void StartDocument(Void); virtual Void StartElement(SFXAnsiStringConstRef uri,SFXAnsiStringConstRef localname, SFXAnsiStringConstRef qname, SFXXMLGrammar::XMLAttrListConstRef attrList); virtual Void IgnorableWhitespace(SFXAnsiStringConstRef string); virtual Void ProcessingInstruction(SFXAnsiStringConstRef target, SFXAnsiStringConstRef data); virtual Void EndPrefixMapping(SFXAnsiStringConstRef prefix); virtual Void StartPrefixMapping(SFXAnsiStringConstRef prefix, SFXAnsiStringConstRef uri); // 解析用のハンドラ virtual Void Comment(SFXAnsiStringConstRef string); virtual Void EndCDATA(Void); virtual Void EndDTD(Void); virtual Void EndEntity(SFXAnsiStringConstRef name); virtual Void StartCDATA(Void); virtual Void StartDTD(SFXAnsiStringConstRef name, SFXAnsiStringConstRef publicId, SFXAnsiStringConstRef systemId); virtual Void StartEntity(SFXAnsiStringConstRef name); // DTD 宣言に関するハンドラ virtual Void NotationDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef publicId, SFXAnsiStringConstRef systemId); virtual Void UnparsedEntityDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef publicId, SFXAnsiStringConstRef systemId, SFXAnsiStringConstRef notationName); // 宣言の通知を取得するハンドラ virtual Void ElementDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef model); virtual Void AttributeDecl(SFXAnsiStringConstRef ename, SFXAnsiStringConstRef aname, SFXAnsiStringConstRef type, SFXAnsiStringConstRef valuedefault, SFXAnsiStringConstRef value); virtual Void InternalEntityDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef value); virtual Void ExternalEntityDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef publicId, SFXAnsiStringConstRef systemId); // エラーの通知を取得するハンドラ virtual Void ErrorReport(SFCErrorConst error, SFXAnsiStringConstRef errInfo); }; // コンストラクタ MyXMLHandler::MyXMLHandler(Void) { return; } // デストラクタ MyXMLHandler::~MyXMLHandler(Void) { return; } // 文書の開始通知を受け取るハンドラ Void MyXMLHandler::StartDocument(Void) { TRACE("document start"); } // 文書の終了通知を受け取るハンドラ Void MyXMLHandler::EndDocument(Void) { TRACE("document end"); } // 要素の開始通知を受け取るハンドラ Void MyXMLHandler::StartElement(SFXAnsiStringConstRef uri, SFXAnsiStringConstRef localname, SFXAnsiStringConstRef qname, SFXXMLGrammar::XMLAttrListConstRef attrList) { // 要素名を表示する TRACE("element: %s start", qname.GetCString()); // 要素の最初の属性対応する列挙子を取得する SFXXMLGrammar::XMLAttrList::Enumerator etor = attrList.GetFirstEnumerator(); // すべての属性の名前と値を表示する while (etor.HasNext()) { SFXXMLGrammar::LPXMLATTR attr = etor.GetNext(); // 次の属性を取得する TRACE("attrname: %s", attr->_attName.GetCString()); // 属性の名前を表示する TRACE("attrvalue: %s", attr->_value.GetCString()); // 属性の値を表示する } } // 要素の終了通知を受け取るハンドラ Void MyXMLHandler::EndElement(SFXAnsiStringConstRef uri, SFXAnsiStringConstRef localname, SFXAnsiStringConstRef qname) { TRACE("element: %s end", qname.GetCString()); } // 文字データの通知を受け取るハンドラ Void MyXMLHandler::Characters(SFXAnsiStringConstRef string, BoolConst /*cdataSection*/) { TRACE("text: %s", string.GetCString()); return; } // ↓以下は空のハンドラ ( イベントを無視する場合も定義する ) // 不要な空白文字の通知を受け取るハンドラ Void MyXMLHandler::IgnorableWhitespace(SFXAnsiStringConstRef string) { return; } // 処理命令の通知を受け取るハンドラ Void MyXMLHandler::ProcessingInstruction(SFXAnsiStringConstRef target, SFXAnsiStringConstRef data) { return; } // 接頭辞と URI 名前空間マッピングのスコープの終了通知を受け取るハンドラ Void MyXMLHandler::EndPrefixMapping(SFXAnsiStringConstRef prefix) { return; } // 接頭辞と URI 名前空間マッピングのスコープの開始通知を受け取るハンドラ Void MyXMLHandler::StartPrefixMapping(SFXAnsiStringConstRef prefix, SFXAnsiStringConstRef uri) { return; } // コメントの通知を受け取るハンドラ Void MyXMLHandler::Comment(SFXAnsiStringConstRef string) { return; } // CDATA セクションの終了通知を受け取るハンドラ Void MyXMLHandler::EndCDATA(Void) { return; } // DTD 宣言の終了通知を受け取るハンドラ Void MyXMLHandler::EndDTD(Void) { return; } // エンティティの終了通知を受け取るハンドラ Void MyXMLHandler::EndEntity(SFXAnsiStringConstRef name) { return; } // CDATA セクションの開始通知を受け取るハンドラ Void MyXMLHandler::StartCDATA(Void) { return; } // DTD 宣言の開始通知を受け取るハンドラ Void MyXMLHandler::StartDTD(SFXAnsiStringConstRef name, SFXAnsiStringConstRef publicId, SFXAnsiStringConstRef systemId) { return; } // エンティティの開始通知を受け取るハンドラ Void MyXMLHandler::StartEntity(SFXAnsiStringConstRef name) { return; } // 記法宣言の通知を受け取るハンドラ Void MyXMLHandler::NotationDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef publicId, SFXAnsiStringConstRef systemId) { return; } // 処理命令の通知を受け取るハンドラ Void MyXMLHandler::UnparsedEntityDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef publicId, SFXAnsiStringConstRef systemId, SFXAnsiStringConstRef notationName) { return; } // 要素型宣言の通知を受け取るハンドラ Void MyXMLHandler::ElementDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef model) { return; } // ATTLIST 宣言の通知を受け取るハンドラ Void MyXMLHandler::AttributeDecl(SFXAnsiStringConstRef ename, SFXAnsiStringConstRef aname, SFXAnsiStringConstRef type, SFXAnsiStringConstRef mode, SFXAnsiStringConstRef value) { return; } // 内部エンティティ宣言の通知を受け取るハンドラ Void MyXMLHandler::InternalEntityDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef value) { return; } // 外部エンティティ宣言の通知を受け取るハンドラ Void MyXMLHandler::ExternalEntityDecl(SFXAnsiStringConstRef name, SFXAnsiStringConstRef publicId, SFXAnsiStringConstRef systemId) { return; } // エラーの通知を受け取るハンドラ Void MyXMLHandler::ErrorReport(SFCErrorConst error, SFXAnsiStringConstRef errInfo) { return; }
例 20.13. SAX パーサーの使い方
SFCError error; // エラー値 SFXXMLSAXParser parser; // SAX パーサー MyXMLHandler handler; // イベント ハンドラ // ハンドラを設定する parser.SetDefaultHandler(&handler); // XML 文書を解析する error = parser.Parse(SFXPath("/file.xml"));
例 20.14. 実行結果
document start element: fruit start element: name start attrname: language attrvalue: english attrname: code attrvalue: ascii text: apple element: name end element: size start text: XS element: size end element: color start text: red element: color end element: fruit end document end parse end
次に、各要素を SFXProperty クラスのインスタンスに格納します。
例 20.15. 解析対象の XML 文書 ( file.xml )
<fruits>
<fruit>
<name>apple</name>
<size>XS</size>
<color>red</color>
</fruit>
<fruit>
<name>grape</name>
<size>SS</size>
<color>purple</color>
</fruit>
<fruit>
<name>peach</name>
<size>M</size>
<color>pink</color>
</fruit>
<fruit>
<name>pineapple</name>
<size>LL</size>
<color>yellow</color>
</fruit>
</fruits>
例 20.16. ハンドラ クラスの定義と実装
// ハンドラ クラス class MyXMLHandler : public SFXXMLDefaultHandler { private: // 要素のペアを格納するクラス SFXProperty _property; // name タグの中身を一時保存する SFXAnsiString _name; // size タグの中身を一時保存する SFXAnsiString _size; // タグの種類 enum KindOfTag {NOTHING, NAME, SIZE, COLOR}; // 現在解析しているタグの種類 KindOfTag _kind; public: // 以後の処理は SAX パーサー ハンドラ クラスの定義と同じ }; // コンストラクタ MyXMLHandler::MyXMLHandler(Void) { _kind = NOTHING; return; } // 要素の開始通知を受け取るハンドラ Void MyXMLHandler::StartElement(SFXAnsiStringConstRef uri, SFXAnsiStringConstRef localname, SFXAnsiStringConstRef qname, SFXXMLGrammar::XMLAttrListConstRef attrList) { if (qname.Equals("name")) { // タグの名前が name のとき _kind = NAME; // name タグを解析中であることを表す } else if (qname.Equals("size")) { _kind = SIZE; } else if (qname.Equals("color")) { _kind = COLOR; } return; } // 要素の終了通知を受け取るハンドラ Void MyXMLHandler::EndElement(SFXAnsiStringConstRef uri, SFXAnsiStringConstRef localname, SFXAnsiStringConstRef qname) { if (qname.Equals("fruit")) { // fruit タグの終わりのとき // _name, _size に保存しておいたテキストを格納する _property.Append(_name, _size); } _kind = NOTHING; return; } // 文字データの通知を受け取るハンドラ Void MyXMLHandler::Characters(SFXAnsiStringConstRef string, BoolConst /*cdataSection*/) { switch (_kind) { case NAME: // name を解析中のとき _name = string; // テキストを _name に格納する break; case SIZE: _size = string; break; default: break; } return; }
XML 文書の各 name 要素と size 要素のテキストをペアにして SFXProperty クラスのインスタンスに格納します。
例 20.17. 解析対象の XML 文書 ( file.xml )
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE Mail SYSTEM "personal.dtd">
<Mail>
<From>&name;</From>
<To>Receiver</To>
<Cc>&Email;</Cc>
<Date> Thu, 7 Oct 1999 11:15:16 -0600</Date>
<Subject>XML Introduction</Subject>
<Body>Comments:<P align = "right">Thanks for reading<br/>this article</P>
<br/>
<P>Hope you enjoyed this article</P>
<P>©right;</P>
</Body>
</Mail>
例 20.18. 検証用の DTD ファイル ( personal.dtd )
<?xml encoding="ISO-8859-1"?> <!-- @version: 10.1--> <!ELEMENT Mail (From, To, Cc?, Date?, Subject, Body)> <!ELEMENT From (#PCDATA)> <!ELEMENT To (#PCDATA)> <!ELEMENT Cc (#PCDATA)> <!ELEMENT Date (#PCDATA)> <!ELEMENT Subject (#PCDATA)> <!ELEMENT Body (#PCDATA | P | Br)*> <!ELEMENT P (#PCDATA | br)*> <!ATTLIST P align (left | right | justify) "left"> <!ELEMENT br EMPTY> <!ENTITY name "sophia"> <!ENTITY Email "&name;@s-cradle.com"> <!ENTITY copyright "Copyright (C) 2005 - 2006 Sophia Cradle Incorporated.">
例 20.19. DTD 付き XML 文書の解析
SFXXMLDOMParser parser; SFCError error; // DTD 付きの XML 文書を解析するため、文法タイプを設定する parser.SetGrammar(SFXXMLGrammar::GRAMMAR_DTD); // XML 文書を DTD で検証するように設定する parser.SetValidationDTD(true); // 外部 DTD を読み込むように設定する parser.SetLoadExternalDTD(true); // XML 文書を解析する error = parser.Parse(SFXPath("/file.xml")); if (error == SFERR_NO_ERROR) { // ルート ノードを取得する SFXXMLDocumentPtr root = parser.GetDocument(); // ドキュメント型を取得する SFXXMLDocumentTypePtr documentType = root->GetDocumentType(); // 外部サブセット ( external DTD subset ) のシステム識別子を取得する // id は "personal.dtd" になる SFXAnsiString id = documentType->GetSystemID(); // DTD に定義されているエンティティを DOMNamedNodeMap として取得する SFXXMLNode::DOMNamedNodeMapPtr entitymap = documentType->GetEntities(); // "name" エンティティの値を取得する // name は "sophia" になる SFXAnsiString name = SFXXMLEntityPtr(entitymap-> GetNamedItem("name"))->GetValue(); }
例 20.20. スキーマ付き XML 文書の解析サンプル コード
SFXXMLDOMParser parser; // コメント 要素を作成するように設定する parser.SetCreateCommentNodes(true); // 名前空間を処理するように設定する parser.SetDoNamespaces(true); // Schema 付きの XML 文書を解析するため、文法タイプを設定する parser.SetGrammar(SFXXMLGrammar::GRAMMAR_SCHEMA); // スキーマを処理するように設定する parser.SetDoSchema(true); // スキーマ付き XML 文書の XSD ファイルを指定する // デフォルト フォルダはアプリのホーム フォルダになる parser.SetSchemaLocation("schema.xsd"); // XML 文書をスキーマで検証するように設定する parser.SetValidationSchema(true); // XML Schema に "annotation" 定義した要素を無視するように設定する parser.SetIgnoreAnnotations(false); // XML 文書を解析する error = parser.Parse(SFXPath("/file.xml"));
例 20.21. SOAP メッセージの作成
SFXSOAPWriter soapwriter; // SOAP メッセージの各要素を生成するオブジェクト SFCError error; // エラー値を保存する変数 // Envelope 要素を作成する // 名前空間接頭辞: デフォルトは "SOAP-ENV" // SOAP バージョン: SFXSOAPParser::SOAP_VERSION_1_2 の場合、"http://www.w3.org/2003/05/soap-envelope" // SFXSOAPParser::SOAP_VERSION_1_1 の場合、"http://schemas.xmlsoap.org/soap/envelope/" // SOAP エンコーディング: "STANDARD" の場合、"http://schemas.xmlsoap.org/soap/encoding/" // "NONE" の場合、SOAP エンコーディングは何も指定しない SFXXMLElementPtr envelope = soapwriter.SetEnvelope("env", SFXSOAPParser::SOAP_VERSION_1_2, "STANDARD"); // Header 要素と Body 要素を作成する if (envelope) { // xmlns:m= "http://www.example.org/timeouts" 名前空間を追加する error = soapwriter.AddNamespace(envelope, "m", "http://www.example.org/timeouts"); // 名前空間が追加されているか確認する if(error != SFERR_NO_ERROR){ TRACE("-----Envelope_NAMESPACE_ERROR:%d-----", error); } // faultcode、faultstring、および faultactor 要素から構成される SOAP Fault 要素を設定する(デフォルトでは Body 要素の子要素となる) soapwriter.SetFault("testing-fault-code","testing-fault-string","testing-fault-actor"); // SOAP Fault 要素に detail 要素を設定する soapwriter.SetFaultDetail("STANDARD")->SetText("testing-fault-detail-message"); // Header 要素を設定する SFXXMLElementPtr header = soapwriter.SetHeader(); if (header) { // isbn:bookname="サッカー ワールド カップ" 属性を追加する error = soapwriter.AddAttribute(header, "bookname", "http://www.example.com/ISBN", "サッカー ワールド カップ", "isbn"); // 属性が追加されているか確認する if(error != SFERR_NO_ERROR){ TRACE("-----HEADER_ATTRIBUTE_ERROR:%d-----", error); } // xmlns:isbn="http://www.example.com/ISBN" 名前空間を追加する error = soapwriter.AddNamespace(header, "isbn", "http://www.example.com/ISBN"); // 名前空間が追加されているか確認する if(error != SFERR_NO_ERROR){ TRACE("-----HEADER_NAMESPACE_ERROR:%d-----", error); } // Header 要素に子要素 Upgrade を追加する // Upgrade 要素の名前空間は Header 要素と同じものに設定する SFXXMLElementPtr elem = soapwriter.SetElement(header, "Upgrade", header->GetNamespaceURI(), header->GetPrefix()); if (elem) { // Upgrade 要素に子要素 SupportedEnvelope を設定する elem = soapwriter.SetElement(elem, "SupportedEnvelope", header->GetNamespaceURI(), header->GetPrefix()); // SupportedEnvelope 要素の属性を追加する error = soapwriter.AddAttribute(elem, "qname", "http://schemas.xmlsoap.org/soap/envelope/", "ns1:Envelope"); // 属性が追加されているか確認する if(error != SFERR_NO_ERROR){ TRACE("-----UPGRADE_ATTRIBUTE_ERROR:%d-----", error); } // SupportedEnvelope 要素の名前空間を追加する error = soapwriter.AddNamespace(elem, "ns1", "http://schemas.xmlsoap.org/soap/envelope/"); // 名前空間が追加されているか確認する if(error != SFERR_NO_ERROR){ TRACE("-----UPGRADE_NAMESPACE_ERROR:%d-----", error); } } } // 作成した SOAP メッセージを保存する error = soapwriter.Save("soapwriter.xml"); // 保存されているか確認する if(error != SFERR_NO_ERROR){ TRACE("-----SOAP_SAVE_ERROR:%d-----", error); } }
例 20.22. 実行結果
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"
env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:m="http://www.example.org/timeouts">
<env:Header isbn:bookname="サッカー ワールド カップ" xmlns:isbn="http://www.example.com/ISBN">
<env:Upgrade>
<env:SupportedEnvelope qname="ns1:Envelope" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/"/>
</env:Upgrade>
</env:Header>
<env:Body>
<env:Fault>
<faultcode>testing-fault-code</faultcode>
<faultstring>testing-fault-string</faultstring>
<faultactor>testing-fault-actor</faultactor>
<detail env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">testing-fault-detail-message</detail>
</env:Fault>
</env:Body>
</env:Envelope>
表 20.18. SOAP エラー メッセージ
| 値 | 解説 |
|---|---|
| 0x699F | SOAP メッセージに Envelope 要素がありません。 |
| 0x69A0 | SOAP メッセージに Body 要素がありません。 |
| 0x69A1 | SOAP メッセージに Fault 要素がありません。 |
| 0x69A2 | SOAP メッセージの Envelope 要素が重複しています。 |
| 0x69A3 | SOAP メッセージに無効な要素があります。 |
| 0x69A4 | 指定した SOAP のバージョンはサポートされません。 |
| 0x69A5 | SOAP メッセージに Fault 要素が含まれます。 |
| 0x0106 | ファイル システムに空き要領がありません。 |
![]() |
XML エラー メッセージ |
|---|---|
関連情報 : SFCErrorEnum | |
例 20.23. SOAP-RPC による Web サービス呼び出し
#define AMAZON_ID " // Amazon の ID を設定する SFMTYPEDEFCLASS(SOAPTest) class SOAPTest : public SFCApplication { SFMSEALCOPY(SOAPTest) private: SFXSOAPRPC _rpc; // SOAP-RPC プロトコルを扱う変数 Void OnSOAP(Void); static Void OnResultSHP_SOAP(SFCError error, const SFXSOAPRPC::Params& result, const SFXSOAPRPC::FAULT& fault, SFXSOAPParserConstRef soap, VoidPtr reference); Void OnResult_SOAP(SFCError error, const SFXSOAPRPC::Params& result, const SFXSOAPRPC::FAULT& fault, SFXSOAPParserConstRef soap); }; Void SOAPTest::OnSOAP() { // メソッド名を設定する _rpc.SetMethodName("ItemSearch"); // SOAP エンコーディングを設定する _rpc.SetEncodingStyle("http://schemas.xmlsoap.org/soap/encoding/"); // 下記のように記述してもよい // _rpc.SetEncodingStyle("STANDARD"); // ターゲットとなる URI を設定する _rpc.SetTargetObjectURI("https://webservices.amazon.com/"); // Web サービスのパラメーターを設定する _rpc.AddParameter("AWSAccessKeyId", SFXBuffer(SFXAnsiString(AMAZON_ID))); _rpc.AddParameter("Keywords", SFXBuffer(SFXAnsiString("caviar"))); _rpc.AddParameter("MerchantId", SFXBuffer(SFXAnsiString("Amazon"))); _rpc.AddParameter("SearchIndex", SFXBuffer(SFXAnsiString("GourmetFood"))); // Web サービスを呼び出す _rpc.Invoke("http://soap.amazon.co.jp/onca/soap?Service=AWSECommerceService", "http://soap.amazon.com", OnResultSHP_SOAP, this); } // Web サービスの結果の通知を受け取るコールバック関数 // error: エラー値, result: Web サービスの戻り値, fault: SOAP Fault 要素, soap : SOAP メッセージ, reference: コールバック関数に渡されるデータ Void SOAPTest::OnResultSHP_SOAP(SFCError error, const SFXSOAPRPC::Params& result, const SFXSOAPRPC::FAULT& fault, SFXSOAPParserConstRef soap, VoidPtr reference) { static_cast<SOAPTestPtr>(reference)->OnResult_SOAP(error, result, fault, soap); } // Web サーバーから受信した SOAP メッセージを処理する関数 Void SOAPTest::OnResult_SOAP(SFCError error, const SFXSOAPRPC::Params& result, const SFXSOAPRPC::FAULT& fault, SFXSOAPParserConstRef soap) { if (error == SFERR_NO_ERROR) { // SOAP メッセージの結果(result: SFXSOAPRPC::Params 配列)をパラメーターに分けて取得する // 列挙子を取得する SFXSOAPRPC::Params::Enumerator paramEtor = result.GetFirstEnumerator(); while (paramEtor.HasNext()) { // 各パラメーターを取得する SFXSOAPRPC::LPPARAMETER temp = paramEtor.GetNext(); // パラメーターの名前を表示する TRACE("parameter-name: %s", temp->_name.GetCString()); // パラメーターのタイプを表示する TRACE("parameter-type: %d", temp->_type); if (!temp->_value.IsEmpty()) { // パラメーターの値を表示する TRACE("parameter-value: %s", ACharConstPtr(temp->_value.GetBuffer())); } } } // エラー メッセージ( SOAP Fault )を表示する else if (error == SFERR_SOAP_FAULT_MESSAGE) { if(!fault._faultactor.IsEmpty()) // faultactor 要素が空でないとき、その内容を表示する TRACE("faultactor: %s", fault._faultactor.GetCString()); if(!fault._faultcode.IsEmpty()) // faultcode 要素が空でないとき、その内容を表示する TRACE("faultcode: %s", fault._faultcode.GetCString()); if(!fault._faultstring.IsEmpty()) // faultstring 要素が空でないとき、その内容を表示する TRACE("faultstring: %s", fault._faultstring.GetCString()); if (fault._faultdetail) // detail 要素が空でないとき、その内容を表示する TRACE("faultstring: %s", fault._faultdetail->GetText().GetCString()); } return; }
例 20.24. SFXSOAPServiceProxy クラス ( WSDL ) を使った Web サービス
// WSDL 文書を利用してプロキシを作成し、ダイナミック バイディングを行う変数 SFXSOAPServiceProxy _wsdl; // サーバーからの返答を受け取るためのコールバック関数を設定する _wsdl.SetNotifyHandler(OnResultSHP, this); // Web サービス記述言語 WSDL を設定する if (_wsdl.SetWSDLDocument("weatherbycity2.xml") == SFERR_NO_ERROR) { // Web サービスの名前を設定する _wsdl.SetServiveName("WeatherByCity"); // Web サービスのポート名を設定する _wsdl.SetPortName("WeatherByCitySoap"); // Web サービスのメソッド名を設定する _wsdl.SetMethodName("GetWeatherByCity"); // パラメーターの値を設定する // Web サービスのユーザー プロパティを設定する _wsdl.SetParameterValue("UserID", SFXBuffer(SFXAnsiString("sophia@s-cradle.com"))); _wsdl.SetParameterValue("Password", SFXBuffer(SFXAnsiString("*******"))); // Web サービスのパラメーターを設定する _wsdl.SetParameterValue("CityName", SFXBuffer(SFXAnsiString("Washington"))); _wsdl.SetParameterValue("StateAbbreviationORCountryName", SFXBuffer(SFXAnsiString("PA"))); // Web サービスを呼び出す _wsdl.Invoke(); }
例 20.25. Web サービス (HTTPS)
// WSDL を利用してプロキシを作成し、ダイナミックバイディングを行う変数 SFXSOAPServiceProxy _wsdl; // サーバーからの返答を受け取るためのコールバック関数を設定する _wsdl.SetNotifyHandler(OnResultSHP, this); // Web サービス記述言語 WSDL を設定する if (_wsdl.SetWSDLDocument("currencyratesbyhttps.xml") == SFERR_NO_ERROR) { // Web サービスの名前を設定する _wsdl.SetServiveName("CurrencyRates"); // Web サービスのポート名を設定する _wsdl.SetPortName("CurrencyRatesSoap"); // Web サービスのメソッド名を設定する _wsdl.SetMethodName("getRate"); // Web サービスのパラメーターを設定する _wsdl.SetParameterValue("CurrencyCode", SFXBuffer(SFXAnsiString("JPY"))); // SSL の検証モードを設定する _wsdl.SetTrustMode(SSL_TRUST_MODE_CHECK); // Web サービスを呼び出す _wsdl.Invoke(); }
表 20.19. WSDL エラー メッセージ
| 値 | 解説 |
|---|---|
| 0x69A6 | WSDL 文書で指定した Web サービスがありません。 |
| 0x69A7 | WSDL 文書で指定した Web サービスのポートがありません。 |
| 0x69A8 | WSDL 文書で指定した Web サービスのポートにバインドできません。 |
| 0x69A9 | WSDL 文書で指定したWeb サービスのメソッドがありません。 |
| 0x69AA | 該当するポート タイプがありません。 |
| 0x69AB | WSDL該当するメッセージがありません。 |
| 0x0106 | ファイル システムに空き要領がありません。 |
![]() |
XML エラー メッセージ |
|---|---|
関連情報 : SFCErrorEnum | |
|
Copyright (C) 2002 - 2008 Sophia Cradle Incorporated All Rights Reserved. |
![]() ![]() ![]()
|