XML:删除父级,克隆给兄弟姐妹

时间:2015-02-09 13:24:41

标签: javascript xml xpath

我的来源xml:

<company>

  <pricelist>
    <category></category>
    <subcategory></subcategory>
    <item></item>
    <item></item>
    <item></item>
    // x number of items
  </pricelist>

  <pricelist>
    <category></category>
    <subcategory></subcategory>
    <item></item>
    <item></item>
    <item></item>
    // x number of items
  </pricelist>

  // x number of pricelists

</company>

现在,想要为给定的xml自动构建一个编辑器:

予。根据子项属性值删除所有不需要的父项。

在我的示例中:删除所有<pricelist> <category>为x,y。

  

我部分解决了这个问题。选择/company/pricelist[category[@id='90' or @id='89']]现在必须删除,可能是removeChild();

II。将<category><subcategory>克隆到所有同级<item>中。

我还没有线索如何开始这个。我想到了一个遍历所有价格表的循环,复制了他们的<category><subcategory>并以某种方式将它们克隆到价格表内的每个兄弟<item>(类别和子类别是唯一的在每个价格表下。)

第二步结果:

<pricelist>
  <category>cat1</category>
  <subcategory>sub1</subcategory>
  <item>
    <category>cat1</category>
    <subcategory>sub1</subcategory>
  </item>
  <item>
    <category>cat1</category>
    <subcategory>sub1</subcategory>
  </item>
  <item>
    <category>cat1</category>
    <subcategory>sub1</subcategory>
  </item>
  ...
</pricelist>

1 个答案:

答案 0 :(得分:1)

正如我所说:两个循环。第一个选择所有剩余价格表,第二个迭代所有item个标签。使用克隆的categorysubcategory填充它们。

&#13;
&#13;
//DO NOT USE THIS SECTION, THIS IS ONLY TO PARSE THE XML STRING SAMPLE INTO A VALID DOCUMENT

        var xmlDoc = document.implementation.createDocument("", "", null);
		xmlDoc.preserveWhiteSpace = false;
		var parser = new DOMParser();
		xmlDoc = parser.parseFromString(document.querySelector("textarea").value.trim(),"text/xml");

//END

//first delete the unwanted pricelist

var unwanted = xmlDoc.querySelectorAll("pricelist > category[id='89'], pricelist > category[id='90']");
Array.prototype.map.call(unwanted, function(element){
    element.parentNode.parentNode.removeChild(element.parentNode); //elements deleted
});

//now parse the rest

//The first loop will select all pricelists and iterates over them using Array.prototype.map.
var priceLists = xmlDoc.querySelectorAll("pricelist");
Array.prototype.map.call(priceLists, function(element){
    //select the category and sub
    var cat = element.getElementsByTagName("category")[0];
    var subCat = element.getElementsByTagName("subcategory")[0];

    //now select all item tags. Iterate over them with a normal loop for more clarity.
    var items = element.getElementsByTagName("item");
    for (var i = 0; i < items.length; ++i)
    {
         var temp = cat.cloneNode(true); //clone the category
         var temp2 = subCat.cloneNode(true); //clone the subcategory
         items[i].appendChild(temp); //append them
         items[i].appendChild(temp2);
    }
});

//    display the XML :: NOT PART OF THE SOLUTION CODE

document.getElementById("display").value = new XMLSerializer().serializeToString(xmlDoc.documentElement);
&#13;
<textarea>

<company>

  <pricelist>
    <category>test 1</category>
    <subcategory>test 2</subcategory>
    <item></item>
    <item></item>
    <item></item>
  </pricelist>

  <pricelist>
    <category>test 3</category>
    <subcategory>test 4</subcategory>
    <item></item>
    <item></item>
    <item></item>
  </pricelist>

  <pricelist >
    <category id="90"></category>
    <subcategory></subcategory>
    <item></item>
    <item></item>
    <item></item>
  </pricelist>
  
   <pricelist >
    <category id="89"></category>
    <subcategory></subcategory>
    <item></item>
    <item></item>
    <item></item>
  </pricelist> 
  
  
</company>
  
  </textarea>
<textarea id="display" style="width: 400px; height: 500px;"></textarea>
&#13;
&#13;
&#13;