2011-11-13 10 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; 

試試這個可能木材加工代碼(未測試):

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」的第二部分處理IE,這在每個實例中都是一個問題。至於第二部分,當然。我個人堅持'childnodes'和'tagName'來迭代。它會簡化你的任務。 – Blender

+0

(實際上,這是我的下一個想法)不要在這裏使用'window';如果你必須使用'this',但更好'if(typeof DOMParser!=「undefined」)'。用'var'聲明'text','parser','xml'等變量。返回一個'NodeList',所以必須是'getElementsByTagName(「person」)[0]'。必須是'childNodes'(區分大小寫)。 DOMParser現在是非常漂亮的跨瀏覽器。對於IE/MSHTML,你有第二個分支;但需要啓用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

這個函數只是按預期工作 –