2017-04-03 65 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