SDom クラス

XMLやHTML のタグ構文を解析して、ツリー構造を形成します。これは一番の自信作です。JScript を意識して設計しました。
更新日 2014-07-29

仕様

JScript では、DOM エレメントを大変簡単に扱えます。コレをC++ 上でも可能にするのがSDomクラスです。SDom はツリー構造を構成し、 それぞれがタグに対応します。正確には(実体である)coreDom を参照・管理するスマートポインタであり、ある時はcoreDom をコレクション としても保持できます。JScript に似た動作を可能にしています。

ソースコード

sdom.h 右クリックで「対象をファイルに保存」でダウンロードしてください。

依存関係

sjstring.hscritical.hも使用してます。同じフォルダに入れておいてね。

メソッド

DOM ツリーを管理する機能が実装されています。JScript と似せて作ってます。JScript を知ってる人ならすぐ使えると思います。

setTagname(), getTagname()

タグ名を設定・取得します。これで最小のDOM ツリー構造(<tagname></tagname>)が成り立ちます。タグ名は大文字小文字を区別します。SJString クラスで管理していますのでunicode で記述できます。
SDom dom;
dom.setTagname( "div" );
SJString str = dom.getTagname();	// str == div

setAttribute(), getAttribute()

属性を設定・取得できます。引数に属性名を与えて該当する値だけを取得する事もできます。
dom.setAttribute( "name=\"programing\" title=\"プログラミグ♪\"" );
dom.setAttribute( "style", "font-weight:bold;");
SJString str = dom.getAttribute( "name" ):		// str == "programing"

createElement(), removeElement()

子エレメントを作成したり、自身を除去します。どちらもエレメント自体への参照を返します。(除去したエレメントは除去前と変わりません。ただ親エレメントはNULL に 設定されています。
SDom refParagraph = dom.createElement( "paragraph" );
refParagraph = refParagraph.removeElement();

children()

子エレメントへの参照をかえします。ゼロから始まる位置番号、もしくはタグ名を指定できます。(タグ名の場合は何番目に現れた要素かも指定できます。デフォルトはゼロ) インデックス値を設定しない場合、子エレメントへのリストを返します(次の説明を参照)
SDom dom;
dom.setTagname( "root" );
dom.createElement( "p0" );
dom.createElement( "p1" );
dom.createElement( "p2" );

SDom refDom1 = dom.children(1);
// refDom1.getTagname() == "p1"

// コレクションオブジェクトを取得して、シーケンシャルにアクセス
SDom coll = dom.children();
for (int n = 0; n < coll.length(); n++)
{
	SJString str = coll[n].getTagname();
	// str == "p0"  [n == 0]
	// str == "p1"  [n == 1]
	// str == "p2"  [n == 2]
}

children(), all(), tags()

それぞれ子エレメント、下位全エレメント(自分を含む)、タグ名を指定しての列挙ができます。SDom インスタンスはリストとしても動きます。
SDom dom;
dom.setTagname( "div" );
for (int n = 0; n < 10; n++)
{
	SDom refNew = dom.createElement( "page" );
	for (int p = 0; p < 3; p++)
	{
		refNew.createElement( "div" );
	}
}

SDom collPage = dom.children();		
// dom の直下にある子エレメントのみのリストを返します。collPage[0] で参照できます。

SDom collDiv = dom.all().tags( "div" );
// dom 以下の全てのエレメントのリストを取得し、
// その中からタグ名が div のエレメントのみ列挙します。

followingElement(), precedingElement()

同じ階層(つまり同じ親に属する)において、直前(または直後)に存在するエレメントへの参照を返します。
SDom dom;
dom.setTagname( "root" );
dom.createElement( "element1");
dom.createElement( "element2");
dom.createElement( "element3");

SDom ref3 = dom.children(2);	// index 番号は0 から始まる
SDom refX = ref3.precedingElement();
if (refX == dom.children(1))
{
	// 真
}

refX = refX.followingElement();
if (refX == ref3)
{
	// 真
}

innerHTML(), outerHTML(), innerText(), outerText(), setHTML()

それぞれエレメントの中にDOM 構文のテキストを挿入・取得したり、DOM 構文で無いテキストを挿入・取得できます。setHTML では エレメント自身をも置き換えます。
SDom dom;
dom.setTagname( "root" );

dom.innerText( "テキスト" );
SJString str = dom.outerText();
// str == "<root>テキスト</root>"

dom.innerHTML( "<p>Mr. Incredible!</p>")
str = dom.outerHTML();
// str == "<root><p>Mr. Incredible!</p></root>"
// 先ほどのテキストはinnerHTML() によって削除されました。

str = dom.outerHTML(TRUE);
// エレメント毎に改行され、階層毎にタブ展開された文字列で返されます。

str = dom.outerHTML( FALSE, TRUE);
// str == "<p>Mr. Incredible!</p>"
// 第2引数でTRUE なら、自身のエレメントを無視したHTML 構文を返します。

dom.setHTML("<X>C-C-C</X>");
str = dom.outerHTML();
// str == "<X>C-C-C</X>"

dom.setHTML("<X>C</X><X>C</X>");
str = dom.outerHTML();
// str == "<root><X>C</X><X>C</X></root>"
// ルートタグの無いHTML 文をsetHTML すると、自動的にroot タグをトップに設定し、
// その配下にエレメントを再現します。

insertElement(), setParent()

どちらも要素を別の要素の下に挿入します。要素を移動させる時などは、removeElement() の戻り値をinsertElement() で挿入する事で実現できます。
SDom dom;
dom.setHTML( "<root><p0></p0><p1></p1></root>" );
SDom refP1 = dom.children(1).removeElement();
dom.children(0).innsertElement( refP1 );

setPos(), getPos()

同じ階層における自要素の(発現)位置を示します。
SDom dom;
dom.setHTML( "<root><p0></p0><p1></p1></root>" );
SDom refP1 = dom.children(1);
int nPos = refP1.getPos();
// nPos == 1

refP1.setPos(0);
SJString str = dom.outerHTML();
//<root><p1></p1><p0></p0></root> 

copyElement()

エレメントとその配下のコピーを作成して、返します。コピーされたエレメントは、属する親がNULL です。
SDom dom;
dom.setHTML( "<root><p>あ</p><p>い</p></root>");
SDom refCopy = dom.children(0).copyElement();
dom.innsertElement( refCopy );

SJString strHTML = dom.outerHTML();
// strHTML == "<root><p>あ</p><p>い</p><p>あ</p></root>"

newRef()

エレメントを指すSDom インスタンスをnew したものへのポインタを返します。不要になったら必ずdelete してください。
SDom dom;
dom.setHTML( "<root><p>あ</p><p>い</p></root>");
LPSDom lpSDom = dom.children(0).newRef();
lpSDom->setTagname("i");
delete lpSDom;

SJString strHTML = dom.outerHTML();

IsClosed()

閉じたタグならTRUE を返します。
SDom dom;
dom.setHTML( "<root>AAA<br />BBB</root>";
BOOL bClosed = dom.children(0).IsClosed();
// bClosed == TRUE

IsDTD()

DTD タグならTRUE を返します。
SDom dom;
dom.setHTML( "<?xml version="1.0" encoding="Shift_JIS"?>\
<?xml-stylesheet type="text/xsl" href="../basic.xsl"?>\
<paragraph></paragraph>";
BOOL bClosed = dom.children(0).IsClosed();
// bClosed == TRUE

IsCommentTag()

タグがコメント(<!--) ならTRUE を返します。
SDom dom;
dom.setHTML(<root><!-- コメント --></root>
BOOL bCommentTag = dom.children(0).IsCommentTag();
// bCommentTag == TRUE

IsEmpty()

SDom インスタンスにまだ何もタグが割り当てられていない場合はTRUE を返します。
SDom dom;
BOOL bEmpty = dom.IsEmpty();
// bEmpty == TRUE;

IsScriptlet()

タグがスクリプトレットである場合はTRUE を返します。
SDom dom;
dom.setHTML(<root><%@page %></root>
BOOL bScriptlet = dom.children(0).IsScriptlet();
// bScriptlet == TRUE

open(), close()

タグを自己閉じタグ(例:<br />)を通常のタグ(<br></br>) に展開したり、 その逆に閉じたりできます。子エレメントがあると閉じる事はできません。
SDom dom;
dom.setTagname("br");
dom.close()
SJString str = dom.outerHTML();
// str == "<br />"

dom.open()
str = dom.outerHTML();
// str == "<br></br>"

changeDTD(), changeCommentTag(), changeScriptlet(), changeDefault()

タグをそれぞれDTDタグ(<?xml )、コメントタグ(<!-- )、スクリプトレット(<% ) に変換 したり、通常のタグ(<root>) に戻したりします。
SDom dom;
dom.setTagname("root");
dom.changeDTD();
SJString str = dom.outerHTML();
// str == "<?root?>"

dom.changeCommentTag();
str = dom.outerHTML();
// str == "<!-- -->"

dom.changeScriptlet();
str = dom.outerHTML();
// str == "<% %>

dom.changeDafault();
// str == "<root></root>"