2011-11-13 11 views
0

これを行う関数を作成しました。XMLのようなテキストをJavaScriptオブジェクトに構文解析する方法

var text="adsf [name]Victor[/name] dummytext [name]Elliot[/name] asdf [name]Jake[/name] asdf [foo]bar[/foo]"; 

alert(readTags(text,'name')); //Victor,Elliot,Jake 
alert(readTags(text,'foo')); //bar 

が、今、私はこの

[person] 
    [name]jake[/name] 
    [age]12[/age] 
[/person] 

のような文字列を受け取る機能を実装し、この

var object={}; 
object['person']={}; 
object['name']='jake'; 
object['age']='12'; 
return(object); 

のようなオブジェクトを返したいが、私はどのようにループするのか分かりませんテキストを通して。開始タグと終了タグの処理方法

[tag] [tag]value[/tag] [/tag] 

ように私は indexOf('[tag]')

lastindexOf('[/tag]')を使用して、右から左と終了タグの開始タグを見つけると考えられますが、これは以前のある

[tag]value[/tag] [tag]value[/tag] 

このような状況では動作しません。機能

function readTags(str,property){ 

    var beginTag='['+property+']'; 
    var endTag='[/'+property+']'; 

    var values=new Array(0); 

    while(str.indexOf(beginTag)!=-1){ 
     values[values.length]=strBetween(str,beginTag,endTag); 
     str=str.substring(str.indexOf(endTag)+endTag.length); 
    } 
    return(values); 
} 

function strBetween(string,strBegin,strEnd){ //StrBetween("abcdef","b","e") //return "cd" 

    var posBegin, posEnd; 

    posBegin=string.indexOf(strBegin); 
    string=string.substring(posBegin + strBegin.length); 
    posEnd=string.indexOf(strEnd); 
    string=string.substring(0,posEnd); 

    if ((posBegin==-1)||(posEnd==-1)){ 
     return(null); 
    }else{ 
     return(string); 
    } 
} 
+1

これを行わないでください。代わりに[JSON](http://json.org/)を使用してください。 – PointedEars

+1

JSONを使用してみませんか? – wannik

+0

@PointedEars私はブログを使用してこのようなロボットがつかむことのできるコンテンツをホストしています。ほとんどすべてがJSONにゴミ箱を追加するか、XMLまたは<>タグを使用できません –

答えて

4

JSONを使用しないと良い理由がない限り、は使用しないでください。 JSONはこれらの問題のすべてを非常にうまく処理し、サーバからクライアントへ、そしてその逆も非常に簡単に浮かべることができます。

しかし、これは楽しいようだから、私は答えを拾うことができるかどうか試してみるでしょう。


あなたの構造は、XMLに似ているので、ちょうど<>とブラケットを交換し、XMLのようにそれを解析:

text = text.replace('[', '<').replace(']', '>'); 

if (typeof DOMParser != "undefined") { 
    var parser = new DOMParser(); 
    var xml = parser.parseFromString(text, 'text/xml'); 
} else { 
    var xml = new ActiveXObject('Microsoft.XMLDOM'); 
    xml.async = 'false'; 
    xml.loadXML(text); 
} 

xmlはあなたが解析できるDOMDocumentを保持している:

xml.getElementsByTagName('person').childnodes; 

試してくださいコード(テストしていない)-working:

function createObject(element) { 
    var object = {}; 

    if (element.childNodes.length > 0) { 
    for (child in element.childnodes) { 
     object[element.tagName] = createObject(child); 
    } 

    return object; 
    } else { 
    return element.nodeValue; 
    } 
} 
+0

スマートなソリューション!それはクロスブラウザですか?今私は 'getElementsByTagName(" * ")'を使用してすべての要素をループし、オブジェクトを生成できると思います。私は正しい? –

+0

'if'の2番目の部分はIEを処理します。これはすべてのインスタンスで問題です。第二の部分は、確かに。私は個人的に 'childnodes'と' tagName'を使って繰り返します。それはあなたの仕事を簡素化します。 – Blender

+0

(これは私の次のアイデアでした)ここでは 'window'を使わないでください。必要ならば 'this'を使いますが、if(typeof DOMParser!=" undefined ")'を使う方が良いでしょう。 'text'、' parser'、 'xml'などの変数を' var'で宣言します。 'NodeList'を返します。したがって、' getElementsByTagName( "person")[0] 'でなければなりません。 'childNodes'でなければなりません(大文字小文字を区別します)。 DOMParserはこれまでにかなりクロスブラウザーです。 IE/MSHTMLには2番目のブランチがあります。ただし、ActiveXのサポートを有効にする必要があります。 "*"を渡すと、すべての要素のNodeListが返されます。しかし、それはフラットなので、あなたはそれからオブジェクトを構築することはできません。あなたは木を横断する必要があります。 E4Xはここで助けます。 – PointedEars

1

を私は、これは、サードパーティのパーサなしで行うことは興味深いものになるだろうと思ったので、私は私に簡単なものを建て:

function parse(code) 
{ 
    var obj = {}, 
     cur = obj, 
     stack = []; 

    code.replace(/\[([^\]]+)\]|([^\[]*)/g, function (match, tagName, text) { 
    if (tagName) 
    { 
     if (tagName.charAt(0) == "/") 
     { 
     /* end tag */ 
     cur = stack.pop(); 
     } 
     else 
     { 
     /* start tag */ 
     stack.push(cur); 
     cur = cur[tagName] = {}; 
     } 
    } 
    else 
    { 
     cur["#text"] = text; 
    } 
    }); 

    return obj; 
} 

var obj = parse(text); 
+0

この関数はちょうど期待どおりに動作します –

関連する問題