オブジェクト索引
HTMLElement オブジェクトは、parseHtml() 関数でパースした HTML 文書中の要素(タグ)を表すオブジェクトです。
例えば
メソッド名 | 説明 |
---|---|
addClass(className) | 要素に className で指定した class 属性を追加する |
addStyle(style) | 要素に style で指定した style 属性を追加する |
after(html) | 要素の後に html を挿入する |
append(html) | 指定された html を要素の最後の子要素として追加する |
attr(attributeName, [attributevalue]) | 指定した属性値を取得または設定する |
before(html) | 要素の前に html を挿入する |
childNodes() | 要素の直下の子要素の配列を返す(すべてのタイプのノード) |
children() | 要素の直下の子要素の配列を返す(HTMLElement のみ) |
className() | 要素の class 属性を返す |
classNames([classNames]) | 要素の class 属性を配列として返す |
cssSelector() | 要素の CSS セレクタを文字列で返す |
getAllComments() | 要素の子要素以下にあるすべてのコメントを返す |
hasClass(className) | class 属性に className が指定されているか判定する |
hasText() | HTMLElement 内にテキストを保持しているか判定する |
html([innerHtml]) | 要素の各子要素の html を生成して返す、または要素の内側の html を設定する |
id() | 要素のid 属性を返す |
nodeName() | 要素の型を文字列で返す |
outerHtml() | 要素全体の html を生成して返す |
ownText() | 要素の直下のテキストをつなぎ合わせて返す |
parent() | 要素の親要素を返す |
parents() | 要素のすべての親(祖先)を返す |
prepend(html) | 指定された html を要素の先頭の子要素として追加する |
remove() | 要素を文書から削除する |
removeAttr(attrKey) | 要素から attrKey で指定した属性を削除する |
removeClass(className) | 要素の class 属性から className を削除する |
select(selector) | selector で指定された CSS セレクタを持つ要素を返す |
tagName([newTagName]) | 要素のタグ名を返す、または設定する |
text([newText]) | 要素中のすべてのテキストをつなぎ合わせて返す、または要素のテキストを書き換える |
toggleClass(className) | 要素に class 属性を追加または削除する |
unwrap() | 要素の一番外側のタグを除去する |
val([newValue]) | 要素が input や textarea などの場合に設定されている値を返す、または値を設定する |
wrap(html) | 指定した html で要素をラップする |
要素に class 属性を追加します。
追加する class 属性を文字列で指定します。
HTMLElement オブジェクト
addClass() メソッドの戻り値は HTMLElement オブジェクトです。複数の class 属性を追加したい場合などでは addClass("cls1").addClass("cls2") という具合に、addClass() をチェインして呼び出すことができます。
既に付けられている class 属性と同じ class を指定して呼び出しても大丈夫です。同じ class 属性が二つ付いてしまうことはありません。例えば <p class="cls1"> という要素に対して addClass("cls1") を実行しても大丈夫です。
一方、addClass("cls1 cls2") など、スペースを含む文字列を指定して addClass() を呼び出した場合、cls1 cls2 の二つの class 属性が付与されるのではなく、スペースの入った "cls1 cls2" というひとつの class 属性が付与されてしまいますのでご注意ください。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<ul class="menu">
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
....
この中にある class="menu" が指定されている ul 要素を取り出し、その要素の class 属性に "mainMenu" を追加してから、展開結果に埋め込む場合の展開の記述は、例えば下記のようになります。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
%parseHtml(htmlText).select(".menu").first().addClass("mainMenu").outerHtml()%
</body>
</html>
parseHtml(htmlText) で htmlText に書かれている html テキストをパースして HTMLDocument オブジェクトを生成します。
HTMLDocument オブジェクトに対して select(".menu") を実行し class 属性に "menu" という指定を持っている要素(この例ではひとつですが、場合によっては複数の可能性があります)を取り出します。
select() の結果は HTMLElements オブジェクトです。(HTMLElement ではありません)select() は、一般に複数の要素を含む HTMLElements を返してくるので、その先頭を first() メソッドで取り出します。メソッド first() の戻り値は HTMLElement オブジェクトです。
取り出した HTMLElement オブジェクトに対して addClass("mainMenu") を実行し class 属性に "mainMenu" を追加します。
最後に outerHtml() メソッドを呼び出して ul 要素全体を展開に埋め込みます。HTMLElement オブジェクトを展開に埋め込むためには明示的に outerHtml() を呼び出す必要があります。
展開の実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<ul class="menu mainMenu">
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
</body>
</html>
first() メソッドを呼ばずに addClass() することも可能です。HTMLElements の addClass() の説明も参照してください。
要素に style 属性を追加します。
追加する style 属性を文字列で指定します。
HTMLElement オブジェクト
既に style 属性が付けられている要素に対して呼び出しても大丈夫です。その場合、既に付けられている style 属性の末尾に、style で指定した style 属性が付加されます。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<ul class="menu" style="margin-top: 20px;">
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
....
この中にある class="menu" が指定されている ul 要素を取り出し、その要素の style 属性に "background-color: #eee" を追加してから、展開結果に埋め込む場合の展開の記述は、例えば下記のようになります。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
%parseHtml(htmlText).select(".menu").first().addStyle("background-color: #eee;").outerHtml()%
</body>
</html>
parseHtml(htmlText) で htmlText に書かれている html テキストをパースして HTMLDocument オブジェクトを生成します。
HTMLDocument オブジェクトに対して select(".menu") を実行し class 属性に "menu" という指定を持っている要素(この例ではひとつですが、場合によっては複数の可能性があります)を取り出します。
select() の結果は HTMLElements オブジェクトです。(HTMLElement ではありません)select() は、一般に複数の要素を含む HTMLElements を返してくるので、その先頭を first() メソッドで取り出します。メソッド first() の戻り値は HTMLElement オブジェクトです。
取り出した HTMLElement オブジェクトに対して addStyle("background-color: #eee;") を実行し style 属性に "background-color: #eee;" を追加します。
最後に outerHtml() メソッドを呼び出して ul 要素全体を展開に埋め込みます。HTMLElement オブジェクトを展開に埋め込むためには明示的に outerHtml() を呼び出す必要があります。
展開の実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<ul class="menu" style="margin-top: 20px;background-color: #eee;">
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
</body>
</html>
first() メソッドを呼ばずに addStyle() することも可能です。HTMLElements の addStyle() の説明も参照してください。
要素の後に html を挿入します。
要素の後ろに挿入する html テキストを指定します。
HTMLElement オブジェクト。挿入された html ではなく、after() のターゲットになった HTMLElement が返される点に注意してください。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<p>段落1</p>
<p>段落2</p>
</body>
</html>
この html に対して、最初の p 要素の後ろに、新たな p 要素を追加してから展開に組み込んでみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-variable name="body" value="parseHtml(htmlText).body()" />
%body.select("p").first().after("<p><em>追加</em>してみました</p>")%
%body.html()%
</body>
</html>
parseHtml() 関数で htmlText をパースし、パース結果から body 部分を取り出して変数 body に入れておきます。
body に対して select("p").first() メソッドを呼び出し body 中の先頭の p 要素を探し出します。
取り出した p 要素に対して after("<p><em>追加</em>してみました</p>") という操作で、html 断片を指定して p 要素を追加しています。
最後に body.html() を実行し、p 要素を追加した後の body の内側を展開しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>段落1</p>
<p><em>追加</em>してみました</p>
<p>段落2</p>
</body>
</html>
before() も参照してください。
html に指定された html をこの要素の最後の子要素として付け加えます。
最後の子要素として付け加えたい html を文字列で指定します。
この HTMLElement オブジェクトが返されます。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<section>
<p>こんにちは</p>
<p>ここで最初の section が終了しました</p>
</section>
</body>
</html>
この htmlText の最初の section の終了直前の位置に "<span>End of the first section</span>" という html 断片を挿入してみましょう。
<wr-variable name="html" value="parseHtml(htmlText)" />
%html.body().select("section").first().append("<span>End of the first section</span>")%
%html.html()%
parseHtml() 関数で htmlText をパースし、得られた HTMLDocument オブジェクトを変数 html に保持しておきます。
html に保持されている HTMLDocument オブジェクトの body() メソッドで body 要素を取り出し、さらに、select("section") で section 要素を洗い出します。洗い出された section 要素の中の先頭の section 要素を first() メソッドで取り出し、そのセクションの最後の子要素になるように append(...) を実行しています。
最後に html.html() で span 要素を追加した後の html を展開しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<section>
<p>こんにちは</p>
<p>ここで最初の section が終了しました</p>
<span>End of the first section</span>
</section>
</body>
</html>
この例では span 要素を挿入しましたが、タグに囲まれていないテキストやコメントなども挿入することができます。
prepend(html) メソッドも参照してください。
指定した名前の属性値を取得または設定します。
取得したい、または、設定したい属性の名前を指定します。
このパラメタを指定した場合には、attributeName で指定した名前の属性に、この attributeValue で指定した値が設定されます。指定した文字列中の & や ' や " などは自動でエスケープされますので、事前にエスケープしておく必要はありません。
既に値が設定されている属性値に、このメソッドで属性値を設定すると、以前に設定されていた値は失われ、このメソッドで設定した値に置き換わります。
このパラメタは省略可能です。
HTMLElement オブジェクト
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<a href="https://www.frameworks.co.jp/">www.frameworks.co.jp</a><br>
....
この htmlText の中にある a 要素の中から http で始まる URL をリンク先に持つものを選別し、その先頭の a 要素に対して、target="_blank" 属性をつけてみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-variable name="body" value="parseHtml(htmlText).body()" />
%body.select("a[href^=http").first().attr("target", "_blank")%
%body.html()%
</body>
</html>
parseHtml() 関数で htmlText をパースし、パース結果から body 部分を取り出して変数 body に入れておきます。
body から "a[href^=http" というセレクタを指定して、http から始まる href 属性をもつ a 要素を探し出します。select() の戻り値は HTMLElements オブジェクトなので first() メソッドで先頭を取り出します。first() メソッドの戻り値は HTMLElement オブジェクトです。
取り出した a 要素に対して target="_blank" という属性を指定します。
最後に html() メソッドで、属性値を書き換えたあとの a 要素を含む body の内側を展開しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
....
<a href="https://www.frameworks.co.jp/" target="_blank">www.frameworks.co.jp</a>
<br>
....
</body>
</html>
タイトル属性に、エスケープが必要になる文字列を指定してみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
%parseHtml("<h1>Hello World</h1>").select("h1").first().attr("title", "&\"").outerHtml()%
</body>
</html>
この例では、parseHtml() 関数に直接 h1 タグの文字列を与えてパースしています。select() で h1 を選び出し、first() で HTMLElement オブジェクトを取得します。
その HTMLElement オブジェクトに対して attr() メソッドで & 記号と " (double quote) を含む title を設定しています。
最後に outerHtml() メソッドで h1 タグ全体を展開しています。結果は下記の様になるでしょう。attr に指定した属性値の、& 記号と " (double quote) はそれぞれ & と " に変換されています。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1 title="&"">Hello World</h1>
</body>
</html>
removeAttr() メソッドも参照してください。
要素の前に html を挿入します。
要素の前に挿入する html テキストを指定します。
HTMLElement オブジェクト。挿入された html ではなく、before() のターゲットになった HTMLElement が返される点に注意してください。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<p>段落1</p>
<p>段落2</p>
</body>
</html>
この html に対して、最後の p 要素の前に、新たな p 要素を追加してから展開に組み込んでみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-variable name="body" value="parseHtml(htmlText).body()" />
%body.select("p").last().before("<p><em>挿入</em>してみました</p>")%
%body.html()%
</body>
</html>
parseHtml() 関数で htmlText をパースし、パース結果から body 部分を取り出して変数 body に入れておきます。
body に対して select("p").last() メソッドを呼び出し body 中の最後の p 要素を探し出します。
取り出した p 要素に対して before("<p>挿入してみました</p>") という操作で、html 断片を指定して p 要素を挿入しています。
最後に body.html() を実行し、p 要素を付け加えた後の body の内側を展開しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>段落1</p>
<p><em>挿入</em>してみました</p>
<p>段落2</p>
</body>
</html>
after() も参照してください。
要素の直下の子要素の配列を返します。
要素の直下の子要素の配列を返します。配列の要素は HTMLElement / HTMLTextNode / HTMLDataNode / HTMLComment のいずれかです。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<h1>Hello <em>World</em>!</h1>
テキストです。
<script>
// script 要素自体は HTMLElement ですが
// script の子要素は HTMLDataNode として扱われます。
</script>
<!-- コメント -->
</body>
</html>
この htmlText の中にある body に対して childNodes() メソッドを呼び出し、得られた結果を表示してみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-for list="parseHtml(htmlText).body().childNodes()" variable="aNode">
<wr-variable name="nodeName" value="aNode.nodeName()" />
<wr-if condition="nodeName != \"HTMLTextNode\" || aNode.isBlank() != true">
<h1>%nodeName%</h1>
</wr-if>
</wr-for>
</body>
</html>
parseHtml() 関数で htmlText をパースしてから body 要素を取り出します。その body 要素に対して childNodes() メソッドを呼び出して子要素の配列を取得しています。
取得した子要素の配列を wr-for の list= に渡してループを実行します。ループの内側ではそれぞれの子要素の nodeName() メソッドを呼び出してノードのタイプを出力しています。
この展開例では nodeName() の戻り値が HTMLTextNode の場合には、そのノードが isBlank() でない、つまり、空白文字以外のテキストを持っている場合にのみ nodeName() の結果を表示するようにしてみました。
この展開の実行結果は下記の様になるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>HTMLElement</h1>
<h1>HTMLTextNode</h1>
<h1>HTMLElement</h1>
<h1>HTMLComment</h1>
</body>
</html>
htmlText 中の "<h1>Hello <em>World</em>!</h1>" の部分は HTMLElement です。
htmlText 中の "テキストです。" の部分は HTMLTextNode です。
htmlText 中の "<script>....</script>" の部分は HTMLElement です。
htmlText 中の "<!-- コメント -->>" の部分は HTMLComment です。
要素の直下の子要素の配列を返します。
直下の要素を保持する HTMLElements オブジェクトを返します。
childNodes() メソッドは、この要素直下のすべてのタイプのノード、つまり、HTMLComment, HTMLDataNode, HTMLTextNode, HTMLElement の配列を返すのに対し、この children() メソッドはこの要素の子ノードの中の HTMLElement のみを選択して返します。そのため、このメソッド戻り値は HTMLElements オブジェクトです。このメソッドは実質的には childNodes() メソッドの戻り値を HTMLElement に限定して返すフィルタです。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<h1>Hello <em>World</em>!</h1>
テキストです。
<script>
// script 要素自体は HTMLElement ですが
// script の子要素は HTMLDataNode として扱われます。
</script>
<!-- コメント -->
</body>
</html>
この htmlText の中にある body に対して children() メソッドを呼び出し、得られた結果を表示してみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-for list="parseHtml(htmlText).body().children().asArray()" variable="anElement">
<h1>%anElement.nodeName()% (%anElement.tagName()%)</h1>
</wr-for>
</body>
</html>
parseHtml() 関数で htmlText をパースしてから body 要素を取り出します。その body 要素に対して children() メソッドを呼び出して子要素の中にある HTMLElement を保持している HTMLElements オブジェクトを取得しています。
取得した HTMLElements オブジェクトの asArra() メソッドを実行して、子要素の HTMLElement の配列を取得し、それを wr-for の list= に渡してループを実行します。ループの内側ではそれぞれの子要素の nodeName() メソッドと tagName() メソッドを呼び出してノードのタイプとタグ名を出力しています。
この展開の実行結果は下記の様になるでしょう。戻り値の HTMLElements には、HTMLElement となるノードだけが含まれています。HTMLTextNode や HTMLComment が含まれることはありません。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>HTMLElement (h1)</h1>
<h1>HTMLElement (script)</h1>
</body>
</html>
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
ペットにもいろいろな種類があります。
<ul>
<li>いぬ</li>
<li>ねこ</li>
</ul>
<ul>
<li>ことり</li>
<li>うさぎ</li>
</ul>
</body>
</html>
この htmlText の中にある ul 要素に一律に class="pet" を付加してみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-variable name="body" value="parseHtml(htmlText).body()" />
%body.children().addClass("pet")%
%body.html()%
</body>
</html>
parseHtml() 関数で htmlText をパースしてから body 要素を取り出し、それを body という変数に保持しておきます。
その body 要素に対して children() メソッドを呼び出して HTMLElements オブジェクトを取得しています。この HTMLElements の中には ul 要素が二つ含まれています。body() の直下には「ペットにもいろいろな種類があります。」という HTMLTextNode がありますが、これは要素ではないので HTMLElements には含まれません。
取得した HTMLElements オブジェクトの addClass() メソッドを使って、HTMLElements 中にある二つの ul 要素の両方に class="pet" を付加しています。
最後に body.html() を実行して class 属性を付加した後の html を生成して展開に組み込んでいます。
この展開の実行結果は下記の様になるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
ペットにもいろいろな種類があります。
<ul class=" pet">
<li>いぬ</li>
<li>ねこ</li>
</ul>
<ul class=" pet">
<li>ことり</li>
<li>うさぎ</li>
</ul>
</body>
</html>
この要素に付けられている class 属性を返します。複数の class 属性が付いている場合には、それらは空白で区切られたひとつの文字列として返されます。
文字列。この要素に付けられている class 属性。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<p class="sample text">className() メソッドは要素に付けられている class 属性を返します</p>
....
この htmlText を下記のような展開で処理してみましょう。
....
[%parseHtml(htmlText).select("p").first().className()%]
....
展開の結果は下記のようになるでしょう。p 要素には sample と text という二つの class 属性が付いていますので、className() メソッドの戻り値は、それらが空白で区切られた文字列になります。
....
[sample text]
....
classNames() メソッドも参照してください。
この要素に付けられている class 属性を文字列の配列として返します。または、この要素に class 属性を一括して設定します。
設定する class 属性を、スペースで区切った文字列で指定します。複数の class 属性を一括して設定できます。このメソッドを使って class 属性を一括設定すると、その時点で設定されていた class 属性はすべてクリアされ、指定された class 属性が(複数)設定されます。classNames には空文字列(長さ0の文字列)を指定することができます。その場合には、その時点で設定されていたすべての class 属性が削除されることになります。
このパラメタは省略可能です。省略された場合には、このメソッドは、その時点でこの要素に付けられている class 属性を文字列の配列として返します。返される配列は、そのまま wr-for の list= に指定することができます。
パラメタ classNames を指定した場合には HTMLElement を返します。
パラメタ classNames が指定されなかった場合には、その時点でつけられている class 属性が文字列の配列として返されます。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<p class="sample text">classNames() メソッドは要素に付けられている class 属性を設定/参照します</p>
....
この htmlText を下記のような展開で処理してみましょう。
....
<wr-for list="parseHtml(htmlText).select(\"p\").first().classNames()" variable="x" count="n">
%n%:%x%<br>
</wr-for>
....
classNames() をパラメタなしで呼び出すと、その時点で要素に付けられている class 属性を文字列の配列として取得することができます。この例では、その文字列配列を wr-for の list= に直接渡して、ループしています。この展開の実行結果は下記のようになるでしょう。
....
1:sample<br>
2:text<br>
....
今度は classNames() メソッドを使って、要素の class 属性を設定してみましょう。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<p class="sample text">classNames() メソッドは要素に付けられている class 属性を設定できます</p>
....
この htmlText の場合 p 要素には sample と text の二つの class 属性が付けられていますが、これを書き換えてみます。下記のような展開で書き換えることができます。
....
<wr-->htmlText をパースします。
得られた HTMLDocument オブジェクトを doc に保持しておきます</wr-->
<wr-variable name="doc" value="parseHtml(htmlText)" />
<wr-->p 要素の class 属性を書き換えます</wr-->
%doc.select("p").first().classNames("hello world")%
<wr-->p 要素の class 属性を表示してみます</wr-->
<wr-for list="doc.select(\"p\").first().classNames()" variable="x" count="n">
%n%:%x%<br>
</wr-for>
....
実行結果は下記の様になるでしょう。もともと p 要素に付けられていた class 属性 sample と text は削除され、classNames() にパラメタで指定した hello と world が class 属性として付けられています。
....
1:hello<br>
2:world<br>
....
classNames() を、パラメタに空文字列を指定して呼び出すことで、その時点で付いている class 属性をクリアすることができます。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<p class="sample text">classNames() で class 属性をまとめてクリアしてみましょう</p>
....
この htmlText を下記の展開で処理してみましょう。
<wr-->htmlText をパースします。
得られた HTMLDocument オブジェクトを doc に保持しておきます</wr-->
<wr-variable name="doc" value="parseHtml(htmlText)" />
<wr-->p 要素の class 属性をクリアします</wr-->
%doc.select("p").first().classNames("")%
<wr-->p 要素の class 属性を表示してみます</wr-->
[%doc.select("p").first().className()%]
実行結果は下記のようになるでしょう。class 属性はクリアされているので className() メソッドの戻り値は空文字列になっています。
....
[]
....
この要素をユニークに指定できる CSS セレクタを返します。
CSS セレクタを文字列で返します。
要素が id 属性を持っているならば、それが返されます。id 属性がない場合には、親要素の CSS セレクタの後ろに '>' が続き、さらに、要素をユニークに特定する CSS セレクタが続く文字列が返されます。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<p>cssSelector()関数は要素を特定する CSS セレクタを返します。</p>
<p>nth-child(n) といったセレクタを返す場合があります。</p>
<p>特定するための CSS セレクタが、必ず何らかの形で生成され返されます。</p>
</body>
</html>
この html の中の最後の p 要素をユニークに特定するための CSS セレクタを表示していましょう。
....
%parseHtml(htmlText).select("p").last().cssSelector()%
....
parseHtml() 関数を使って htmlText をパースして HTMLDocument オブジェクトを入手します。入手した HTMLDocument に対して select("p") を実行し、p 要素を抽出します。抽出される p 要素は3件になりますが、ここではその最後の p 要素を last() で取り出しています。3番めの p 要素の cssSelector() を求めて表示しています。
実行結果は下記のようになるでしょう。
html > body > p:nth-child(3)
この要素の子要素以下にある、すべてのコメントを返します。
HTMLComment オブジェクトの配列
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head>
<!-- コメント#0 -->
<title>Title</title>
</head>
<body>
<!-- コメント#1 -->
<p>
<!-- コメント#2 -->
今日は良い<em>天気<!-- コメント#3 --></em>です。
</p>
</body>
</html>
この html に対して、body 内にあるすべてのコメントを抽出して展開に組込んでみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-for list="parseHtml(htmlText).body().getAllComments()" variable="comment">
%comment.outerHtml()%<br>
</wr-for>
</body>
</html>
parseHtml() 関数で htmlText をパースし、パース結果から body 部分を取り出し、getAllComments() メソッドを呼び出してコメントのリストを取得します。
getAllComments() メソッドの戻り値は HTMLComment オブジェクトの配列です。そのまま wr-for の list= に指定することができます。
個々のコメントを outerHtml() メソッドで展開しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<!-- コメント#1 -->
<br>
<!-- コメント#2 -->
<br>
<!-- コメント#3 -->
<br>
</body>
</html>
HTMLDocument オブジェクトにも同様のメソッドがあります。
この要素に指定された class 属性が指定されているかどうかを調べます。
要素に指定されているかどうかを調べたい class 属性の名前を指定します。
このメソッドの戻り値は真偽値 ( true または false ) です。引数 className に指定された class 属性を持っている場合に true を返します。持っていない場合に false を返します。
クラス属性が指定されているかどうかの判定では、大文字/小文字は区別されません。例えば class="cls1" と指定されている要素に対して hasClass("Cls1") を実行すると true になります。
この HTMLElement が表している要素が、何らかのテキストを保持している場合に true を返します。保持しているテキストが空白だけの場合は false を返します。
真偽値 true または false
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<p>
このパラグラフは空ではありません
</p>
<p></p>
<p>
</p>
<p>
<span>
<strong></stron>
</span>
</p>
<p>
<!-- このパラグラフは空です -->
</p>
この htmlText の中にある、各 p 要素について hasText() メソッドを呼び出してどういう結果が得られるか試してみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<ol>
<wr-for list="parseHtml(htmlText).select(\"p\").asArray()" variable="p">
<li>%p.hasText()%</li>
</wr-for>
</ol>
</body>
</html>
parseHtml() 関数で htmlText をパースして HTMLDocument オブジェクトを取得します。
取得した HTMLDocument オブジェクトに対して select("p") を実行し p 要素をすべて洗い出した結果を保持している HTMLElements オブジェクトを取得します。
各 p 要素について hasText() を呼び出したいので HTMLElements に対して asArray() メソッドを呼び出し wr-for の list= に指定してループを実行します。ループ内では、洗い出した p 要素に対応する HTMLElement オブジェクトに対して hasText() を呼び出してその結果を出力しています。
実行結果は下記の様になるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<ol>
<li>true</li>
<li>false</li>
<li>false</li>
<li>false</li>
<li>false</li>
</ol>
</body>
</html>
空白だけの p 要素の場合には hasText() は false を返します。また、コメントだけの p 要素の場合にも hasText() は false を返します。
この要素の内側の各子要素の html を生成して返します。または、この要素の内側の html を設定します。
パラメタを指定して html() メソッドを呼び出すと、この要素の子要素が一旦削除されます。その後、 innerHtml に指定された html をパースした結果得られた要素が、この要素の子要素になります。 パラメタを指定せずに html() メソッドを呼び出すと、その時点でこの要素の子要素になっている各要素の html 表現の連接が文字列で返されます。
パラメタを指定して呼び出した場合には HTMLElement オブジェクトが返されます。 パラメタを省略して呼び出した場合は文字列が返されます。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<p>
<img src="a.png">
</p>
</body>
</html>
body 要素の html() を呼び出すと下記のとおりになります。html() は body の子要素のみ html 化して返します。
<p>
<img src="a.png">
</p>
body 要素の outerHtml() を呼び出すと下記のとおりになります。
<body>
<p>
<img src="a.png">
</p>
</body>
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<p>
<img src="a.png">
</p>
</body>
</html>
この html の body 要素の内側を html() メソッドで書き換えた結果を展開に組み込んでみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
%parseHtml(htmlText).body().html("<h1>Hello World!</h1>").html()%
</body>
</html>
parseHtml() 関数で htmlText をパースしてから body() で body 要素を取り出します。body の内側の html を html("<h1>Hello World!</h1>") で書き換えてから、結果を html() で出力しています。
結果は下記の様になるでしょう。もともと htmlText に含まれていた p 要素や img 要素は削除されてなくなっているのが判ります。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
html() メソッドをパラメタなしで呼び出して要素の html 表現を生成する場合、エスケープが必要な文字、例えば & や < > などは、状況に応じて適切にエスケープされた状態で返されます。メソッド名が表しているとおり、返される文字列は、妥当性のある html テキストです。さらなるエスケープ処理は必要ありません。このあたりの動作は html() メソッドと text() メソッドとで異なる点に注意してください。
要素に付けられている id 属性を返します。
要素に付けられている id 属性を文字列で返します。要素に id 属性が付されていない場合には長さ0の空文字列が返されます。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body id="b0">
<p>Hello World!</p>
</body>
</html>
この htmlText の中にある body の id を取り出して展開に組み込んでみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<h1>%parseHtml(htmlText).body().id()%</h1>
</body>
</html>
parseHtml() 関数で htmlText をパースしてから body 要素を取り出します。その body 要素に対して id() メソッドを呼び出して id 属性の値を取り出しています。
この展開の実行結果は下記の様になるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>b0</h1>
</body>
</html>
同じ htmlText をベースにして、今度は body 要素ではなく p 要素に対して id() を呼び出してみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<h1>%parseHtml(htmlText).select("p").first().id()%</h1>
</body>
</html>
parseHtml() 関数で htmlText をパースしてから、select("p") で p 要素を取り出し、さらにその先頭の p 要素を取り出します。その p 要素に対して id() メソッドを呼び出して id 属性の値を取り出しています。
この展開の実行結果は下記の様になるでしょう。id 属性が指定されていない要素に対して id() メソッドを呼び出すと空文字列が返されます。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1></h1>
</body>
</html>
要素の型を返します。childNodes() メソッドなどを呼び出すと、型の判らない子要素の配列が得られますが、各子要素の型を調べる時に nodeName() メソッドが役立ちます。
要素の型の名前を文字列で返します。HTMLElement オブジェクトに対してこのメソッドを呼び出すと "HTMLElement" が返されます。
この要素全体の html を生成して返します。
この要素全体の html で表現した文字列
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<div class="mainNav">
<ul>
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
</div>
この htmlText 中の ul 要素を取り出して展開中に組み込んでみましょう。
....
%parseHtml(htmlText).select("ul").first().outerHtml()%
....
parseHtml() 関数で htmlText をパースし select("ul").first() で最初の ul 要素を取り出しています。最後に outerHtml() を呼び出して、ul 要素全体を展開に組み込んでいます。
この展開の実行結果は下記の様になるでしょう。
....
<ul>
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
....
outerHtml() ではなく html() を使った場合の実行結果は下記の通りです。
....
<li>menuItem1</li>
<li>menuItem2</li>
....
ul 要素自身は html() では出力されず、ul の子要素だけが出力対象になります。
このメソッドを使って html を生成する場合、エスケープが必要な文字、例えば & や < > などは、必要な部分で適切にエスケープされたものが返されます。さらにエスケープを考慮する必要はありません。
この要素の直下のテキストをつなぎ合わせて返します。戻り値には子要素が持っているテキストは含まれません。
この要素のテキストが文字列で返されます。
以下のような展開を考えてみます。
....
<h1>%parseHtml("<p>Hello <b>there</b> now!</p>").select("p").first().ownText()%</h1>
....
<p>Hello <b>there</b> now!</p> という html をパースしてから p 要素を取り出します。その上で、p 要素に対して ownText() メソッドを実行しています。
実行結果は下記の様になるでしょう。p 要素直下のテキスト Hello と now! だけが結果に含まれます。text() メソッドの場合には p の子要素の b の中のテキストも得られますが ownText() の場合には子要素のテキストは結果に含まれません。
....
<h1>Hello now!</h1>
....
この要素の親要素を返します。
この要素の親要素の HTMLElement オブジェクトを返します。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html lang="ja">
<head><title>Title</title></head>
<body>
<p>こんにちは!いかがお過ごしですか?</p>
<p>みなさん<em>こんにちは!</em>今日は良い天気です</p>
</body>
</html>
この html テキストの em 要素を取り出し、その親要素のタグ名を出力してみましょう。
....
%parseHtml(htmlText).select("em").first().parent().tagName()%
....
parseHtml() 関数を使って htmlText をパースし HTMLDocument オブジェクトを入手します。入手した HTMLDocument オブジェクトに対して select("em") メソッドを実行し、htmlText 中にある em 要素を洗い出します。select() メソッドの戻り値は HTMLElements オブジェクトなので、first() メソッドで先頭の HTMLElement オブジェクトをひとつだけ取り出します。
その次に、em 要素に対して parent() メソッドを呼び出して親要素を取り出したら tagName() メソッドで親要素のタグ名を出力しています。実行結果は "p" になるでしょう。
同様に、下記のような展開で body 要素の親要素のタグ名を展開中に組み込んでみましょう。
....
%parseHtml(htmlText).body().parent().tagName()%
....
parseHtml() 関数を使って htmlText をパースし HTMLDocument オブジェクトを入手します。入手した HTMLDocument オブジェクトに対して body() メソッドを実行し、htmlText 中にある body 要素を取り出します。
次に、body 要素に対して parent() メソッドを呼び出して親要素を取り出したら tagName() メソッドで親要素のタグ名を出力しています。実行結果は "html" になるでしょう。
parents() メソッドも参照してください。
要素のすべての親(祖先)を返します。
すべての親(祖先)を含む HTMLElements オブジェクトを返します。直親がリストの先頭側、もっとも遠い祖先がリストの末尾側に格納されています。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html lang="ja">
<head><title>Title</title></head>
<body>
<p>Hello <em>World</em>!</p>
</body>
</html>
この html テキスト中にある em 要素に対して parents() メソッドを実行し、得られたリストにどのように親要素が入っているのかを調べてみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-for list="parseHtml(htmlText).select(\"em\").first().parents().asArray()" variable="node">
<h1>%node.tagName()%</h1>
</wr-for>
</body>
</html>
parseHtml() 関数を使って htmlText をパースし HTMLDocument オブジェクトを入手します。入手した HTMLDocument オブジェクトに対して select("em") メソッドを実行し、htmlText 中にある em 要素を洗い出します。select() メソッドの戻り値は HTMLElements オブジェクトなので、first() メソッドで先頭の em 要素をひとつだけ取り出します。
その次に、em 要素に対して parents() メソッドを呼び出して親要素を取り出したら parents() の結果として得られた HTMLElements オブジェクトに対して asArray() メソッドを実行し HTMLElements オブジェクトを HTMLElement オブジェクトの配列に変換します。変換して得られた配列を wr-for の list= に渡してループを実行します。ループの内側では、その親のタグ名を表示しています。
実行結果は下記の様になるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>p</h1>
<h1>body</h1>
<h1>html</h1>
</body>
</html>
html に指定された html をこの要素の先頭の子要素として付け加えます。
先頭の子要素として付け加えたい html を文字列で指定します。
この HTMLElement オブジェクトが返されます。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<section>
<p>ここから最初の section が始まります</p>
<p>こんにちは</p>
</section>
</body>
</html>
この htmlText の最初の section の先頭の位置に "<!-- 最初のセクションの開始位置 -->" というコメントを挿入し、さらに先頭に "始まります" という文字列を挿入してみましょう。
<wr-variable name="html" value="parseHtml(htmlText)" />
%html.body().select("section").first().prepend("<!-- 最初のセクションの開始位置 -->").prepend("始まります")%
%html.html()%
parseHtml() 関数で htmlText をパースし、得られた HTMLDocument オブジェクトを変数 html に保持しておきます。
html に保持されている HTMLDocument オブジェクトの body() メソッドで body 要素を取り出し、さらに、select("section") で section 要素を洗い出します。洗い出された section 要素の中の先頭の section 要素を first() メソッドで取り出し、そのセクションの先頭の子要素になるように prepend(...) を実行しています。
最後に html.html() でコメントを追加した後の html を展開しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<section>
始まります
<!-- 最初のセクションの開始位置 -->
<p>ここから最初の section が始まります</p>
<p>こんにちは</p>
</section>
</body>
</html>
この例ではコメントとテキストを挿入しましたが、タグに囲まれた html 断片も挿入することができます。
append(html) メソッドも参照してください。
remove() はこの要素を文書から削除します。要素が子要素を持っている場合は、それらもすべて削除されます。
null です。削除された要素にはアクセスできなくなりますので HTMLElement は返されません。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<p>
remove() メソッドは要素を削除するときに使用します。
<img src="a.png">
</p>
</body>
</html>
この htmlText 中にある p 要素を取り出し、その中にある最初の img 要素を削除した結果を展開に組み込んでみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-variable name="p" value="parseHtml(htmlText).select(\"p\").first()" />
%p.select("img").first().remove()%
%p.outerHtml()%
</body>
</html>
parseHtml() 関数で htmlText をパースし、パース結果から p 要素部分を取り出し、変数 p に格納します。
この例では p 要素の数はひとつだけですが、一般には select() の結果には複数の要素が含まれている場合がありますので first() メソッドで選択された p 要素の最初のひとつだけを取り出します。この first() の戻り値が HTMLElement オブジェクトです。
取り出した p 要素に対して select("img") メソッドを呼び出し img 要素を抽出してから、first() でその先頭の img 要素を取り出し、その img 要素を remove() で削除しています。
最後に p.outerHtml() を実行して、img が削除されたあとの p 要素の html を生成して展開に組み込んでいます。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<p> remove() メソッドは要素を削除するときに使用します。 </p>
</body>
</html>
この要素から引数で指定した名前の属性を削除します。
削除したい属性の属性名を指定します。
HTMLElement オブジェクト
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<p>
<a href="https://www.frameworks.com/" target="_blank">click here</a>
</p>
このような html から target="_blank" の部分を除去したい場合の展開は下記のようになります。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<wr-variable name="doc" value="parseHtml(htmlText)" />
%doc.select("a[target=_blank]").first().removeAttr("target")%
%doc.body().html()%
</body>
</html>
parseHtml(htmlText) で htmlText に書かれている html テキストをパースして HTMLDocument オブジェクトを生成します。パースした結果は、変数 doc にとっておきます。
doc に対して select("a[target=_blank]") を実行し target="_blank" という属性指定を持っている a 要素を取り出します。
select の戻り値は HTMLElements オブジェクトなので first()メソッドで先頭を取り出します。first()メソッドの戻り値は HTMLElement オブジェクトです。
取り出した HTMLElement オブジェクトに対して removeAttr("target") を実行し target 属性を削除します。
最後に doc の body に対して html() メソッドを呼び出して body 要素の内側を展開に埋め込みます。
実行結果は下記の様になるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<p> .... <a href="https://www.frameworks.com/">click here</a> .... </p>
</body>
</html>
first() メソッドを呼ばずに removeAttr() することも可能です。HTMLElements の removeAttr() の説明も参照してください。
要素に指定されている class 属性を削除します。
削除したい class 属性を文字列で指定します。
removeClass() メソッドの戻り値は HTMLElement オブジェクトです。複数の class 属性を削除したい場合などでは removeClass("cls1").removeClass("cls2") という具合に、removeClass() をチェインして呼び出すことができます。
要素に付けられていない class 属性を指定して removeClass() を呼び出しても大丈夫です。その場合、呼び出しても何も実行されません。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<ul class="menu subMenu">
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
....
この中にある class="menu" が指定されている ul 要素を取り出し、その要素の class 属性に指定されている "subMenu" を削除してから、展開結果に埋め込む場合の展開の記述は、例えば下記のようになります。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
%parseHtml(htmlText).select(".menu").first().removeClass("subMenu").outerHtml()%
</body>
</html>
parseHtml(htmlText) で htmlText に書かれている html テキストをパースして HTMLDocument オブジェクトを生成します。
HTMLDocument オブジェクトに対して select(".menu") を実行し class 属性に "menu" という指定を持っている要素(この例ではひとつですが、場合によっては複数の可能性があります)を取り出します。
select() の結果は HTMLElements オブジェクトです。(HTMLElement ではありません)select() は、一般に複数の要素を含む HTMLElements を返してくるので、その先頭を first() メソッドで取り出します。メソッド first() の戻り値は HTMLElement オブジェクトです。
取り出した HTMLElement オブジェクトに対して removeClass("subMenu") を実行し class 属性から "subMenu" を削除します。
最後に outerHtml() メソッドを呼び出して ul 要素全体を展開に埋め込みます。HTMLElement オブジェクトを展開に埋め込むためには明示的に outerHtml() を呼び出す必要があります。
展開の実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<ul class="menu">
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
</body>
</html>
first() メソッドを呼ばずに removeClass() することも可能です。HTMLElements の removeClass() の説明も参照してください。
select() は、要素と、その子要素を対象に、指定された CSS セレクタを満たす要素を選択して返します。
選択条件を指定する CSS セレクタを与えます。空文字列は与えられません。
条件を満たす HTMLElement オブジェクトを含んだ HTMLElements オブジェクトが返されます。
selector には CSS や jQuery で使用されるセレクタとほぼ同様の表記が使用できます。selector に指定可能な表現は下表のとおりです。
パターン |
一致する対象 |
例 |
* |
すべての要素 | * |
tag名 |
tag名 に指定された名前のタグを持つ要素 | div |
ns|E |
名前空間 ns に属する E | fb|name は、<fb:name> にマッチ |
#id |
id に指定された id 属性を持つ要素 | div#wrap , #logo |
.class |
class に指定された class 属性を持つ要素 | div.left , .result |
[attr] |
attr に指定された属性(任意の値)を持つ要素 | a[href] , [title] |
[^attrPrefix] |
属性名が attrPrefix で始まる属性を持つ要素 | [^data-] , div[^data-] |
[attr=val] |
属性 attr の値が val である要素 | img[width=500] , a[rel=nofollow] |
[attr="val"] |
属性 attr の値が val である要素 | span[hello="Cleveland"][goodbye="Columbus"] , a[rel="nofollow"] |
[attr^=valPrefix] |
属性 attr の値が valPrefix で始まっている要素 | a[href^=http:] |
[attr$=valSuffix] |
属性 attr の値が valSuffix で終わっている要素< | img[src$=.png] |
[attr*=valContaining] |
属性 attr の値が valContaining を含んでいる要素 | a[href*=/search/] |
[attr~=regex] |
属性 attr の値が正規表現 regex に一致する要素 | img[src~=(?i)\\.(png|jpe?g)] |
これらのセレクタを組み合わせて使うことができます | div.header[title] |
|
コンビネータ |
||
E F |
E 要素の子孫の F 要素 | div a , .logo h1 |
E > F |
E 要素の直下の子要素 F | ol > li |
E + F |
E 要素のすぐ後ろの F 要素 | li + li , div.head + div |
E ~ F |
E 要素の後ろの F 要素 | h1 ~ p |
E, F, G |
E, F, G のいずれかにマッチする要素 | a[href], div, h3 |
擬似セレクタ |
||
:lt(n) |
その要素の、同レベルの要素中での位置番号が n より小さい要素 | td:lt(3) は、各行の、最初の 2 つのセルにマッチします |
:gt(n) |
その要素の、同レベルの要素中での位置番号が n より小さい要素 | td:gt(1) は、各行の先頭以外のセルにマッチします |
:eq(n) |
その要素の、同レベルの要素中での位置番号が n である要素 | td:eq(0) は、各行の先頭のセルにマッチします |
:has(selector) |
selector に指定されたセレクタにマッチする要素を少なくともひとつ含んでいる要素 | div:has(p) は、ひとつ以上の p 要素を含んでいる div にマッチします |
:not(selector) |
セレクタ selector にマッチしない要素(HTMLElements の not() メソッドの説明も参照してください) | div:not(.logo) は logo という class 属性を持っていないすべての div にマッチしますdiv:not(:has(div)) は子要素に div を持たない div にマッチします |
:contains(text) |
text に指定されたテキストを含む要素。検索では大文字小文字は区別されません。text が要素またはいずれかの子要素に含まれている場合にマッチします。 | p:contains(jsoup) は jsoup という文字列を含む p 要素にマッチします |
:matches(regex) |
regex に指定された正規表現にマッチするテキストを含む要素。text が要素またはいずれかの子要素に含まれている場合にマッチします。 | td:matches(\\d+) は、数字を含む table の cell にマッチします。div:matches((?i)login) は、(?i)login という正規表現(大文字小文字を区別しない login という文字列)にマッチする文字列を、直接またはいずれかの子要素に含む div 要素にマッチします。 |
:containsOwn(text) |
text で指定された文字列を直接含む要素。大文字小文字は区別されません。 | p:containsOwn(jsoup) は jsoup という文字列を直接含む p 要素にマッチします |
:matchesOwn(regex) |
regex に指定された正規表現に一致するテキストを直接含む要素。 | td:matchesOwn(\\d+) は、数字を直接含んでいる table の cell にマッチします。 div:matchesOwn((?i)login) は、(?i)login という正規表現に一致するテキストを直接含んだ div にマッチします。 |
これらのセレクタを組み合わせて使うことができます | .light:contains(name):eq(0) |
|
疑似クラス(Structural pseudo selectors) |
||
:root |
ドキュメントのルート要素。HTML の場合には html 要素がマッチします。 |
:root |
:nth-child(an+b) |
先頭から N 番めの要素にマッチ。N は an+b という式も指定可能。a と b にはいずれも整数を指定する。負でも良い。n は 0 以上の整数値をとる。 nth-child(odd) という記述も可能。これは nth-child(2n+1)と同じ意味になる。 nth-child(even) という記述も可能。これは nth-child(2n) と同じ意味になる。 |
tr:nth-child(2n+1) は、奇数番目の tr 要素にマッチ:nth-child(10n-1) は、9番目、19番目、 29番目、などにマッチli:nth-child(5) は 5 番目の li 要素にマッチ |
:nth-last-child(an+b) |
後ろから N 番めの要素にマッチする。それ以外は :nth-child() と同じ。 |
tr:nth-last-child(-n+2) は最後の2行の tr 要素にマッチ |
:nth-of-type(an+b) |
先頭から N 個目の同じ型の要素にマッチする。それ以外は :nth-child() と同じ。 |
img:nth-of-type(2n+1) |
:nth-last-of-type(an+b) |
後ろから N 個目の同じ型の要素にマッチする。それ以外は :nth-child() と同じ。 |
img:nth-last-of-type(2n+1) |
:first-child |
親要素の先頭の子要素でなければならない | div > p:first-child |
:last-child |
親要素の最後の子要素でなければならない | ol > li:last-child |
:first-of-type |
親要素の子要素の中で同じ型の要素の先頭の要素 | dl dt:first-of-type |
:last-of-type |
親要素の子要素の中で同じ型の要素の最後の要素 | tr > td:last-of-type |
:only-child |
親要素の子要素が自分だけの要素 | |
:only-of-type |
親要素の子要素の中に同じ型の要素がない要素 | |
:empty |
子要素を持っていない要素 |
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html lang="ja">
<head><title>Title</title></head>
<body>
<p>こんにちは!いかがお過ごしですか?</p>
<p>Hello World!</p>
<p style="font-size: 200%;">みなさん、こんにちは!今日は良い天気です</p>
</body>
</html>
この htmlText を加工して「こんにちは」を含む p 要素に style="color:red;" を追加してから展開に組こんでみましょう。
<!DOCTYPE html>
<html lang="ja">
<head><title>Title</title></head>
<body>
<wr-variable name="body" value="parseHtml(htmlText).body()" />
%body.select("p:contains(こんにちは)").addStyle("color: red")%
%body.html()%
</body>
</html>
parseHtml() 関数を使って htmlText をパースし HTMLDocument オブジェクトを入手します。入手した HTMLDocument オブジェクトに対して body() メソッドを実行し、body 要素を取り出します。取り出した body 要素は body という変数に確保しておきます。
その次に、body に対して select("p:contains(こんにちは)") メソッドを実行し「こんにちは」というテキストを含む p 要素を抽出します。この例では 2 つの p 要素が該当します。select() の戻り値として、該当した二つの p 要素に対応する HTMLElement オブジェクト二つを含む HTMLElements オブジェクトが返されます。
抽出したした p 要素を含む HTMLElements オブジェクトに対して addStyle("color: red") メソッドを実行し、二つの p 要素に style="color: red" という属性を追加します。
その後、body に対して body.html() を実行し、加工された body の内側を展開に組込んでいます。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Title</title>
</head>
<body>
<p style="color: red">こんにちは!いかがお過ごしですか?</p>
<p>Hello World!</p>
<p style="font-size: 200%;color: red">みなさん、こんにちは!今日は良い天気です</p>
</body>
</html>
要素のタグ名を返します。または、要素のタグ名を設定します。
この引数は省略可能です。引数を指定せずに tagName() メソッドを呼び出すと、要素のタグ名が文字列で返されます。
引数に文字列を指定して呼び出すと、この要素のタグ名が引数に指定された文字列に書き換えられます。この場合の tagName() メソッドの戻り値は HTMLElement オブジェクトになります。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<ul class="list">
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
....
class 属性に "list" を持つ要素を探し出して、その要素のタグ名を調べてみましょう。
<!DOCTYPE html>
<html lang="ja">
<head><title>Title</title></head>
<body>
<p>%parseHtml(htmlText).select(".list").first().tagName()%</p>
</body>
</html>
parseHtml(htmlText) で htmlText に書かれている html テキストをパースして HTMLDocument オブジェクトを生成します。
HTMLDocument オブジェクトに対して select(".list") を実行し class 属性に "list" という指定を持っている要素(この例ではひとつですが、場合によっては複数の可能性があります)を取り出します。
select() の結果は HTMLElements オブジェクトです。(HTMLElement ではありません)select() は、一般に複数の要素を含む HTMLElements を返してくるので、その先頭を first() メソッドで取り出します。メソッド first() の戻り値は HTMLElement オブジェクトです。
取り出した HTMLElement オブジェクトに対して tagName() を実行してタグ名を取得します。
この展開の実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html lang="ja">
<head><title>Title</title></head>
<body>
<p>ul</p>
</body>
</html>
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
....
<div class="mainNav">
<ul>
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
</div>
....
class 属性に "mainNav" を持つ div 要素を探し出して、その要素のタグ名 div から nav に変更した結果を展開に埋め込んでみましょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
%parseHtml(htmlText).select("div.mainNav").first().tagName("nav").outerHtml()%
</body>
</html>
parseHtml(htmlText) で htmlText に書かれている html テキストをパースして HTMLDocument オブジェクトを生成します。
HTMLDocument オブジェクトに対して select("div.mainNav") を実行し class 属性に "mainNav" という指定を持っている div 要素(この例ではひとつですが、場合によっては複数の可能性があります)を取り出します。
select() の結果は HTMLElements オブジェクトです。(HTMLElement ではありません)select() は、一般に複数の要素を含む HTMLElements を返してくるので、その先頭を first() メソッドで取り出します。メソッド first() の戻り値は HTMLElement オブジェクトです。
取り出した HTMLElement オブジェクトに対して tagName("nav") を実行しタグを div から nav に書き換えます。
最後に outerHtml() メソッドを呼び出して nav 要素全体を展開に埋め込みます。HTMLElement オブジェクトを展開に埋め込むためには明示的に outerHtml() を呼び出す必要があります。
展開の実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<nav class="mainNav">
<ul>
<li>menuItem1</li>
<li>menuItem2</li>
</ul>
</nav>
</body>
</html>
この要素と、そのすべての子要素中のテキストをつなぎ合わせて返します。または、この要素のテキストを書き換えます。
このパラメタは省略可能です。text() メソッドを、パラメタなしで呼び出した場合、この要素以下のテキストが文字列で返されます。このパラメタを指定して呼び出した場合、この要素のテキストが指定された文字列で置き換えられます。置き換える場合、このメソッド呼び出し時点でのこの要素のテキストや子要素はすべて失われます。
パラメタを指定して呼び出した場合は、要素のテキストが指定された文字列で書き換えられた上で、書き換え対象となった要素の HTMLElement オブジェクトが返されます。
パラメタなしで呼び出した場合はこの要素のテキストが文字列で返されます。
以下のような展開を考えてみます。
....
<h1>%parseHtml("<p>Hello <b>there</b> now!</p>").select("p").first().text()%</h1>
....
<p>Hello <b>there</b> now!</p> という html をパースしてから p 要素を取り出します。その上で、p 要素に対して text() メソッドを実行しています。
実行結果は下記の様になるでしょう。p 要素直下のテキスト Hello と now! だけではなく、p の子要素の b の中のテキストも得られています。text() メソッドが返しているのは p 要素の内側のテキストです。
....
<h1>Hello there now!</h1>
....
以下のような展開を考えてみます。
....
<h1>%parseHtml("<p>Hello <b>there</b> now!</p>").select("p").first().text("Good morning!").text()%</h1>
....
<p>Hello <b>there</b> now!</p> という html をパースしてから p 要素を取り出します。その上で、p 要素に対して text("Good morning!") メソッドを実行して、p 要素の内側のテキストを書き換えています。最後に text() メソッドで設定したテキストを取り出しています。
実行結果は下記の様になるでしょう。text() メソッドが返しているのは p 要素の内側のテキストです。p 要素自体が書き換えられているわけではありません。
....
<h1>Good morning!</h1>
....
展開例(2)のバリエーションとして下記の展開を考えてみます。
....
<div>%parseHtml("<p>Hello <b>there</b> now!</p>").select("p").first().text("Good morning!").outerHtml()%</div>
....
最後に呼び出しているメソッドを outerHtml() に変更してあります。実行結果は下記の様になります。p 要素の内側が書き換えられているだけであることがわかります。一方で、p 要素の子要素だった b 要素は失われていることも判ります。
<div><p>Good morning!</p></div>
要素に class 属性を追加または削除します。
追加または削除する class 属性を文字列で指定します。
要素が className に指定された class 属性を持っていない場合にはそれが追加されます。要素が className に指定された class 属性を既に持っている場合にはそれが削除されます。
toggleClass() メソッドの戻り値は HTMLElement オブジェクトです。複数の class 属性を操作したい場合などでは toggleClass("cls1").toggleClass("cls2") という具合に、toggleClass() をチェインして呼び出すことができます。
addClass() と removeClass() も参照してください。
要素の一番外側のタグを除去します。
HTMLElement, HTMLTextNode, HTMLComment オブジェクトのいずれかが返されます。unwrap() される前の要素の先頭の子要素が返されます。
<strong><span>最初の子要素</span><em>強調</em></strong> という html を unwrap() すると <strong> タグが除去され <span>最初の子要素</span><em>強調</em> が残りますが、この時、unwrap() メソッドの戻り値は <span>最初の子要素</span> の部分に対応する HTMLElement オブジェクトになります。
<strong>テキスト<em>強調</em></strong> という html を unwrap() すると <strong> タグが除去され テキスト<em>強調</em> が残りますが、この時、unwrap() メソッドの戻り値は「テキスト」の部分に対応する HTMLTextNode オブジェクトになります。
<strong><!-- コメントです --><em>強調</em></strong> という html を unwrap() すると <strong> タグが除去され <!-- コメントです --><em>強調</em> が残りますが、この時、unwrap() メソッドの戻り値は <!-- コメントです --> の部分に対応する HTMLComment オブジェクトになります。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<p>一部分を<span class="strong"><em>強調</em></span>してみます</p>
</body>
</html>
この html に対して <span class="strong"><em>強調</em></span> と記述されている部分の <span> タグを除去してから、展開に組込んでみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-variable name="body" value="parseHtml(htmlText).body()" />
%body.select("span.strong").first().unwrap()%
%body.html()%
</body>
</html>
parseHtml() 関数で htmlText をパースし、パース結果から body 部分を取り出して変数 body に入れておきます。
body に対して "span.strong" というセレクタを指定して select() メソッドを呼び出し、class 属性に "strong" が指定されている span 要素を探し出します。select() の戻り値は HTMLElements オブジェクトなので first() メソッドで先頭を取り出します。first() メソッドの戻り値は HTMLElement オブジェクトです。
次に、unwrap() を呼び出すと、<span> タグが取り除かれるので <em>強調</em> が残ります。
最後に html() メソッドで、変形した後の em 要素を含む body の内側を展開しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>一部分を<em>強調</em>してみます</p>
</body>
</html>
wrap() も参照してください。
val() はこの HTMLElement オブジェクトが表している要素が input や textarea などの場合に、その要素に設定されている値を返します。または、値を設定します。
このパラメタは省略可能です。要素に値を指定する場合にこのパラメタを指定します。値は文字列であたえてください。
HTMLElement オブジェクト
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<form>
<input type="text" value="value_of_text">
</form>
</body>
</html>
この htmlText 中にある input 要素に指定されている値 (value= に指定されている値)を取り出して表示してみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-variable name="input_value" value="parseHtml(htmlText).select(\"input\").first().val()" />
<h1>%input_value%</h1>
</body>
</html>
parseHtml() 関数で htmlText をパースし、パース結果から input 部分を取り出します。
この例では input 要素の数はひとつだけですが、一般には select() の結果には複数の要素が含まれている場合がありますので first() メソッドで選択された input 要素の最初のひとつだけを取り出します。
取り出した input 要素に対して val() メソッドを呼び出し、value= に指定されている値を取り出して h1 タグの中に表示しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>value_of_text</h1>
</body>
</html>
今度は input 要素に指定されている値 (value= に指定されている値)を設定し、さらに設定した値を取り出して表示してみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-variable name="input" value="parseHtml(htmlText).select(\"input\").first()" />
<h1>%input.val()%</h1>
%input.val("Hello!")%
<h1>%input.val()%</h1>
</body>
</html>
parseHtml() 関数で htmlText をパースし、パース結果から input 部分を取り出してます。この例では input 要素の数はひとつだけですが、一般には select() の結果には複数の要素が含まれている場合がありますので first() メソッドで選択された input 要素の最初のひとつだけを取り出します。取り出した input 要素を変数 input に保存しておきます。
最初に、もともと input 要素に指定されていた値を h1 タグの中に表示しています。
次に、val() メソッドにパラメタ "Hello!" を渡して input 要素の value= の値を書き換えています。
最後に、書き換えられたあとの input 要素の値を h1 タグの中に表示しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>value_of_text</h1>
<h1>Hello!</h1>
</body>
</html>
要素を、与えられた html でラップします。
要素を wrap する html を指定します。
HTMLElement オブジェクト。wrap される前の HTMLElement が返される点に注意してください。
htmlText という複数行テキストの要素を持つテンプレートがあり、そのテンプレートで作成したページの、この要素の値に下記のような html が記述されている場合を考えます。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<p>一部分を<span class="strong">強調</span>してみます</p>
</body>
</html>
この html に対して <span class="strong">強調</span> と記述されている部分を <stron>強調</strong> に書き換えてから、展開に組込んでみましょう。
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<wr-variable name="body" value="parseHtml(htmlText).body()" />
%body.select("span.strong").first().wrap("<strong></strong>").unwrap()%
%body.html()%
</body>
</html>
parseHtml() 関数で htmlText をパースし、パース結果から body 部分を取り出して変数 body に入れておきます。
body に対して "span.strong" というセレクタを指定して select() メソッドを呼び出し、class 属性に "strong" が指定されている span 要素を探し出します。select() の戻り値は HTMLElements オブジェクトなので first() メソッドで先頭を取り出します。first() メソッドの戻り値は HTMLElement オブジェクトです。
取り出した span 要素に対して wrap("<strong></strong>") という操作で span 全体を strong で wrap します。この時点で <strong><span class="strong">強調</span></strong> という構造に変形された状態になります。
次に、unwrap() を呼び出して、span タグを取り除きます。この時 unwrap() の対象になるのは、wrap() が実行される前の <span class="strong">強調</span> である点に注意してください。span タグが unwrap() で取り残されるので <strong>強調</strong> という形に変形されます。
最後に html() メソッドで、変形した後の strong 要素を含む body の内側を展開しています。
実行結果は下記のようになるでしょう。
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>一部分を<strong>強調</strong>してみます</p>
</body>
</html>
この例では <strong></strong> という単純な html で wrap しましたが、任意の深さの html を指定して要素を wrap することもできます。
例えば <span class="cls1"><em></em></span> というような html で wrap することも可能です。
unwrap() も参照してください。