2017-04-03 16 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] + create + XML + document)があります。 XML文字列を作成するのかXML文書を作成するのかは明確ではありません。 – RobG

+0

私は質問を投稿する前に研究を行い、同じ問題を扱った結果はありません – Giest

答えて

1

文書は、HTML文書である場合、のdocument.createElementは、それがXML文書の場合、タグのケースが保存されるのに対し、小文字にタグ名を変更すること

注意。また、HTML文書では、利用できない可能性があるカスタムおよび未知のtagnamesのサポートに頼っているので、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

注:これはテストされていないので、私は離れなければなりません。しかし、これはあなたにコメントの出発点を与えるはずです。 Forty3の答えが、少しより簡潔かつ用途やXMLドキュメントではなく、HTMLドキュメントに非常に類似し

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%にはならなかった。私は次のように私がプリティアを得ることができました: function insertXML { \t let doc = xml; \t let = 1; \tを行う{ \t \t場合(キー==のNUM){ \t \t \t newelem =のdocument.createElement(値)とします。 \t \t \t doc.appendChild(newelem); \t \t \t break; \t \t}他{ \t \t \t NUM = NUM​​ + 1。 \t \t} \t} while(doc = doc。最後の子); } @ Forty3 – Giest

+1

@ Giestありがとうございました。回答がある場合は、回答として投稿して受け入れる必要があります。 HTMLドキュメントの場合、* document.createElement *はXML要素ではなくHTML要素を作成することに注意してください。 HTMLドキュメントの場合、タグ名は小文字に変換されますが、XMLの場合は大文字と小文字が維持されるため、重要です。ユビキタスではない[*カスタムHTML要素*](https://www.w3.org/TR/custom-elements/)のサポートにも依存しています。 – RobG

関連する問題