2017-04-03 56 views
0

我有一個鍵和值的列表,我打算根據這些信息創建一個xml。分層創建DOM

我的目錄回報:

1 person 
2 information 
3 name 
3 surname 
2 address 
3 street 
3 country 

我想生成xml:

<xml> 
    <person> 
     <information> 
      <name></name> 
      <surname></surname> 
     </information> 
     <address> 
      <street></street> 
      <country></country> 
     </address> 
    </person> 
</xml> 

我有元素的列表,而遍歷這些元素將分層創建XML文檔。我已經有這個代碼:

var elements = document.getElementsByClassName('elements'); 
var xml = document.createElement('xml'); 

for (var i = 0; i < elements.length; i++) { 
    var key = elements[i].getAttribute('data-key'); 
    var value = elements[i].getAttribute('data-value'); 

    console.log(key +' -> '+ value); 

    // HERE: create new elements appendChild "var xml" 
} 
+1

關於創建XML文檔,當然有[*許多問題*](http://stackoverflow.com/search?q= [javascript] +創建+ XML +文檔),肯定其中一個是重複的?目前尚不清楚您是要創建一個XML字符串還是一個XML文檔。 – RobG

+0

我在發佈問題之前做過調查,沒有處理相同問題的結果 – Giest

回答

1

非常類似於Forty3的答案,但有點簡潔,使用和XML文檔,而不是HTML文檔。

注意,如果文檔是一個HTML文件,然後使用document.createElement改變標記名小寫,而如果它是一個XML文檔,該標記的情況下被保留。另外,在HTML文檔中,它依賴於對自定義標記名稱和未知標記名稱的支持(可能無法使用),所以更好地使用XML文檔。

我已經創建了一個數據源,它似乎來自文檔,所以希望它合理地近似您正在使用的內容。我已經在關卡上進行了一些最低限度的驗證,應該有更多的輸入驗證來確保它符合某種標準格式。

function buildDoc() { 
 

 
    // Create an XML document to use to create the elements 
 
    var doc = document.implementation.createDocument(null, null, null); 
 

 
    var data = document.getElementsByClassName('elements'); 
 
    var root = doc.createElement('xml'); 
 
    var parent = root; 
 
    var level = 0; 
 
    var node, tagname; 
 

 
    for (var i=0, iLen=data.length; i<iLen; i++) { 
 
    dataNode = data[i]; 
 
    node = doc.createElement(dataNode.dataset.value);   
 
    nodeLevel = dataNode.dataset.key; 
 

 
    // Can only add nodes at level 1 or higher 
 
    if (nodeLevel <= 0) { 
 
     console.log('Level ' + nodeLevel + ' is invalid. Can only create nodes at level 1 or higher'); 
 
     return; 
 
    } 
 

 
    // If node at same level, is sibling of current parent 
 
    // If node at lower level, go back levels and parents to same level 
 
    // Append node, then make node the parent 
 
    if (nodeLevel <= level) { 
 
     while (nodeLevel < level) { 
 
     parent = parent.parentNode; 
 
     --level; 
 
     } 
 
     parent = parent.parentNode.appendChild(node); 
 

 
    // If node at higher level, is child of current parent 
 
    // Next node might higher again, so set parent to node 
 
    } else if (nodeLevel > level){ 
 
     parent = parent.appendChild(node); 
 
     level = nodeLevel; 
 
    } 
 
    } 
 
    // Return the root 
 
    return root; 
 
} 
 

 

 
window.onload = function() { 
 
    console.log(buildDoc().outerHTML); 
 
};
<div> 
 
    <span class="elements" data-key="1" data-value="Person">1 person</span><br> 
 
    <span class="elements" data-key="2" data-value="information">2 information</span><br> 
 
    <span class="elements" data-key="3" data-value="name">3 name</span><br> 
 
    <span class="elements" data-key="3" data-value="surname">3 surname</span><br> 
 
    <span class="elements" data-key="2" data-value="address">2 address</span><br> 
 
    <span class="elements" data-key="3" data-value="street">3 street</span><br> 
 
    <span class="elements" data-key="3" data-value="country">3 country</span><br> 
 
    <span class="elements" data-key="2" data-value="address">2 address</span><br> 
 
    <span class="elements" data-key="3" data-value="street">3 street</span><br> 
 
    <span class="elements" data-key="3" data-value="country">3 country</span><br> 
 
</div>

PS。由於缺少對data-*屬性的支持,因此這可能不會在IE 10或更低版本中運行。

1

注意:這是未經測試,我需要離開。但是,這應該給你一個評論的起點。

var elements = document.getElementsByClassName('elements'); 
var xml = document.createElement('xml'); 
var curElem = xml; 
var curDepth = 0; 

for (var i = 0; i < elements.length; i++) { 
    var key = elements[i].getAttribute('data-key'); 
    var value = elements[i].getAttribute('data-value'); 

    console.log(key +' -> '+ value); 

    // HERE: create new elements appendChild "var xml" 

    // Create the new element 
    var elem = document.createElement(value); 

    // If we are further down the hierarchy, simply add the child 
    if (key > curDepth) { 
     curElem.appendChild(elem); 
    } else if (key == curDepth) { 
     // We are a sibling of our current containing element 
     // so simply add to the parent 
     curElem.parentElement.appendChild(elem); 
     curElem = elem; 
    } else if (key < curDepth) { 
     // We are at some point ABOVE our current element 
     // so start walking UP until we reach the level indicated 
     // and then add the element to the parent 
     while (curDepth >= key) { 
      curElem = curElem.parentElement; 
      curDepth--; 
     } 
     curElem.parentElement.appendChild(elem); 
    } 
    curElem = elem; 
    curDepth = key; 
} 
+0

您的答案接近解決方案,但我嘗試過,結果並不是100%。我能得到我pretedia與以下內容: function insertXML(xml,key,value) { \t let doc = xml; \t let num = 1; \t做{ \t \t如果(鍵== NUM​​){ \t \t \t讓newelem =使用document.createElement(值); \t \t \t doc.appendChild(newelem); \t \t \t break; \t \t} else { \t \t \t num = num + 1; \t \t} \t} while(doc = doc。最後一個孩子); } 謝謝@ Forty3 – Giest

+1

@ Giest-如果您有答案,您應該將其作爲答案發布並接受它。請注意,如果您在HTML文檔中,那麼* document.createElement *會創建HTML元素,而不是XML元素。這一點很重要,因爲對於HTML文檔,標籤名稱將被轉換爲小寫字母,但對於XML,案例將被保留。它也依賴於對[*自定義HTML元素*](https://www.w3.org/TR/custom-elements/)的支持,這並不是普遍存在的。 – RobG