質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

5回答

5425閲覧

HTMLのリスト構造をJavascriptの配列に変換したい

takumi123

総合スコア59

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2016/07/04 14:18

編集2016/07/04 14:48

###前提・実現したいこと
マインドマップをブラウザ上で作成できるサービスを作っています。
ライブラリを使ってマインドマップの各要素の追加や削除、編集は任せることができましたが、データベースへの保存・読み込みは自分でやる必要があります。

###解決したい問題
データベースから各要素を読み込んで反映させることはできましたが、保存ができていません。
具体的には下記のHTMLコードをJavascriptのコード欄にある形に仕上げたいです。

###該当のソースコード

html

1<ol> 2 <li>0-1</li> 3 <li>0-2</li> 4 <li>0-3 5 <ol> 6 <li>1-1</li> 7 <li>1-2</li> 8 <li>1-3 9 <ol> 10 <li>2-1</li> 11 <li>2-2</li> 12 </ol> 13 </li> 14 <li>1-4</li> 15 </ol> 16 </li> 17 <li>0-4</li> 18 <li>0-5</li> 19</ol>

javascript

1[0-1,0-2,0-3,[1-1,1-2,1-3,[2-1,2-2],1-4],0-4,0-5]

リストはどこまでも深くなっていくため、単純なループではなく再帰的な関数を用意する必要があると思いますが、なかなかいいアイデアが思いつかず困っています。

###回答を参考に試してみた事

  • yamato_hikawa様

まずは入れ子になっていない単純なリスト構造を配列化する仕組みを考えましょう。
以下のコードでできました。

html

1<ol> 2 <li class="node">0-1</li> 3 <li class="node">0-2</li> 4 <li class="node">0-3</li> 5</ol>

javascript

1var count = $(".node").length; 2var array = []; 3for(var i=0;i<count;i++){ 4 var tmp_data = $(".node").eq(i).text(); 5 array.push(tmp_data); 6} 7console.log(array); //["0-1", "0-2", "0-3"]

次は入れ子のリスト構造を配列化したいのですが何か良いアイデアはありますでしょうか?
私も考え中です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2016/07/04 15:16

マインドマップのライブラリは何をお使いでしょうか。もし自作で無い場合は配布元URLを追記いただけないでしょうか。
guest

回答5

0

王道じゃないかもしれませんが……

まず、htmlのol全体を取得します。jQueryのhtml()とかでガリッと。
そして、半角スペースと改行を置換で取り除き1行の文字列にします。
更に次のルールで置換します。

  1. ^<ol><li> => ["
  2. <ol><li> => ",["
  3. </li></ol></li><li> => "],"
  4. </li></ol> => "]
  5. </li><li> => ","

=> ["0-1","0-2","0-3",["1-1","1-2","1-3",["2-1","2-2"],"1-4"],"0-4","0-5"]

文字列なので
hoge = eval(置換後の文字列が入った変数)
で配列化してあげればいいかなと

それと、""で囲っているのは文字列として扱うためですので、計算した数字がほしいのなら”はなしです。

投稿2016/07/04 15:06

oskbt

総合スコア1895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takumi123

2016/07/04 15:24

置換する方法ですか。 全く頭に無かった方法なので非常に興味深いです。 調べて一度やってみたいと思います。 回答いただきありがとうございます!
guest

0

それ以前に、保存のためだけに変換するのですか?
保存したい部分のルート要素の html() を呼び出したら子ノード孫ノードまで一発で文字列に変換できるので、これを保存すればいいんじゃないでしょうか?
ロードも楽ですよ。

投稿2016/07/04 15:03

Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takumi123

2016/07/04 15:08

回答いただきありがとうございます。なるほど、HTML自体を保存して呼び出す。 気が付きませんでした。 ただ、今回私が作るサービスはマインドマップ×ブログという形で、各ノードがブログタグにもなります。そのため、各要素を分けてデータベースに保存する必要があるため、このような形にする必要があると思います。 貴重な意見ありがとうございました。新しい視点でした!
guest

0

ベストアンサー

まずは入れ子になっていない単純なリスト構造を配列化する仕組みを考えましょう。
入れ子をどう処理するかはその後ですね。
単純なリスト構造を配列化する処理が関数化できれば、それを使いまわせると思います。

再帰パターン

javascript

1var convertArray = function($list) { 2 var $li = $list.children('li'), 3 arr = []; 4 5 [].map.call($li, function(el, index) { 6 var $childList = $(el).children('ol'), 7 text = el.childNodes.item(0).nodeValue.trim(), 8 childArr; 9 10 arr.push(text); 11 12 if ($childList.length > 0) { 13 childArr = convertArray($childList); 14 arr.push(childArr); 15 } 16 }); 17 18 return arr; 19}; 20 21var $ol = $('ol').eq(0); 22var arr = convertArray($ol); 23console.log(arr); // ["0-1","0-2","0-3",["1-1","1-2","1-3",["2-1","2-2"],"1-4"],"0-4","0-5"] 24 25/* 配列型→文字列型に変換する場合 */ 26console.log(JSON.stringify(arr));

文字列置換パターン

他の方が仰っていた文字列置換で行う形は下記で出来ました。

javascript

1var $ol = $('ol'), 2 listHtml = $ol[0].outerHTML; 3 4/* 改行・半角スペース取り除き */ 5listHtml = listHtml.replace(/[\n\s]/g, ''); 6 7/* 配列文字列化 */ 8var str = listHtml 9.replace(/^<ol><li>/, '["') 10.replace(/<ol><li>/g, '",["') 11.replace(/<\/li><\/ol><\/li><li>/g, '"],"') 12.replace(/<\/li><\/ol>/g, '"]') 13.replace(/<\/li><li>/g, '","'); 14 15/* 配列化 */ 16var arr = JSON.parse(str); 17 18console.log(arr); //["0-1","0-2","0-3",["1-1","1-2","1-3",["2-1","2-2"],"1-4"],"0-4","0-5"]

投稿2016/07/04 14:33

編集2016/07/05 13:49
yamato_hikawa

総合スコア2092

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takumi123

2016/07/04 14:50

単純なリスト構造を配列化することはできました。質問に追記いたしました。
guest

0

あ、出遅れた。

JavaScript

1function tree_to_array( $_ol ) { 2 var arr = [], $_n = $_ol.find( 'li > .node > .node__text, li > ol' ); 3 $_n.each( function() { 4 var $_t = $( this ), t = ( $_t.prop( 'tagName' ) === 'ol' ) ? tree_to_array( $_t ) : $_t.text(); 5 if ( t ) arr.push( t ); 6 } ); 7 return arr; 8} // (未テスト) 9```一応ライブラリのサンプルの構造をもとに書いてみました。

投稿2016/07/05 12:13

kei344

総合スコア69364

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takumi123

2016/07/05 12:15

回答ありがとうございます。 しっかり読ませていただきます!
guest

0

配列の構造について

生成される配列に違和感を感じます。

JavaScript

1<ol id="mind-map"> 2 <li>0-1</li> 3 <li>0-2</li> 4 <li>0-3 5 <ol> 6 <li>1-1</li> 7 <li>1-2</li> 8 <li>1-3 9 <ol> 10 <li>2-1</li> 11 <li>2-2</li> 12 </ol> 13 </li> 14 <li>1-4</li> 15 </ol> 16 </li> 17 <li>0-4</li> 18 <li>0-5</li> 19</ol> 20 21<script> 22'use strict'; 23var array = sample(document.getElementById('mind-map')); 24console.log(array); // [0-1,0-2,0-3,[1-1,1-2,1-3,[2-1,2-2],1-4],0-4,0-5] 25</script>

「0-3」の子要素を array[3] に置いてますが、両方とも array[2] に存在すべきものじゃないでしょうか。
また、「0-3」 の子要素が2つ以上存在した場合に構造が破綻してしまいます。

アルゴリズム

  1. ある要素の子要素郡から fistChild のテキスト値を元にした配列を生成する(※)
  2. 子要素郡で childNode.elements.length > 0 なら、children に対しても再帰処理させる事で 1. を適用する

textContent では子要素郡のテキストも参照するので firstChild に限定します。

コード

HTML

1<ol id="mind-map"> 2 <li>0-1</li> 3 <li>0-2</li> 4 <li>0-3 5 <ol> 6 <li>1-1</li> 7 <li>1-2</li> 8 <li>1-3 9 <ol> 10 <li>2-1</li> 11 <li>2-2</li> 12 </ol> 13 </li> 14 <li>1-4</li> 15 </ol> 16 </li> 17 <li>0-4</li> 18 <li>0-5</li> 19</ol> 20 21<script> 22'use strict'; 23function getArrayByListElement (listElement) { 24 var array = []; 25 26 for (var i = 0, children = listElement.children, l = children.length; i < l; i++) { 27 var childNode = children[i], 28 children2 = childNode.children, 29 textNode = childNode.firstChild, 30 map = Array.prototype.map; 31 32 if (textNode.nodeType === textNode.TEXT_NODE) { 33 array[i] = {firstText: textNode.data.trim()}; 34 } 35 36 if (children2.length > 0) { 37 array[i].children = map.call(children2, getArrayByListElement); 38 } 39 } 40 41 return array; 42} 43 44var array = getArrayByListElement(document.getElementById('mind-map')); 45console.log(JSON.stringify(array)); // [{"firstText":"0-1"},{"firstText":"0-2"},{"firstText":"0-3","children":[[{"firstText":"1-1"},{"firstText":"1-2"},{"firstText":"1-3","children":[[{"firstText":"2-1"},{"firstText":"2-2"}]]},{"firstText":"1-4"}]]},{"firstText":"0-4"},{"firstText":"0-5"}] 46</script>

Re: takumi123 さん

投稿2016/07/05 02:41

編集2016/07/05 02:46
think49

総合スコア18156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問