2017-04-03 1 views
0

키와 값의 목록이 있으며이 정보를 기반으로 XML을 만들려고합니다.DOM을 계층 적으로 만들기

내 목록 리턴 :

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

그리고 내가 XML을 생성하려면 : 이러한 요소를 순회하는 계층 적 XML 문서를 생성 할 때,

<xml> 
    <person> 
     <information> 
      <name></name> 
      <surname></surname> 
     </information> 
     <address> 
      <street></street> 
      <country></country> 
     </address> 
    </person> 
</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] + create + XML + document)가 있습니다. XML 문자열 또는 XML 문서를 만들지는 명확하지 않습니다. – RobG

+0

질문을 올리기 전에 조사를했는데 동일한 문제를 다루는 결과가 없었습니다 – Giest

답변

1

Forty3의 대답과 유사하지만 HTML 문서가 아닌 간결하고 사용하기 쉬운 XML 문서입니다. 문서 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. 이것은 데이터 - * 속성에 대한 지원 부족으로 인해 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 %는되지 않았습니다. 나는 다음과 함께 내가 pretingia를 얻을 수 있었다 : function insertXML { \t let doc = xml; \t let = 1; \t 할 { \t \t 경우 (키 == 인분) { \t \t \t newelem = document.createElement (값)을 보자; \t \t \t doc.appendChild (newelem); \t \t \t 중단; \t \t한다} else { \t \t \t NUM NUM = + 1; \t \t} \t} while (doc = doc.막내); } 감사합니다 @ Forty3 – Giest

+1

@ Giest - 답변이있는 경우 대답으로 게시하고 수락해야합니다. HTML 문서에있는 경우 * document.createElement *는 XML 요소가 아닌 HTML 요소를 만듭니다. HTML 문서의 경우 태그 이름이 소문자로 변환되기 때문에 중요한데 XML의 경우 대소 문자가 보존됩니다. 유비 쿼터스가 아닌 [* custom HTML 요소 *] (https://www.w3.org/TR/custom-elements/)에 대한 지원도 필요합니다. – RobG

관련 문제