2017-03-02 87 views
0

我對上一次在下面的帖子中發佈的同一模塊有疑問。似乎,處理XML解析是相當困難的。 elementTree具有非常大的文檔。nodejs elementtree npm xml解析和合並

我有以下template_XML文件:

<?xml version="1.0" encoding="UTF-8"?> 
<Tailoring xmlns="http://checklists.nist.gov/xccdf/1.2" id="xccdf_org.open-scap_tailoring_example"> 
<status>incomplete</status> 
<version time="2013-01-15T16:00:00.000+02:00">1.0</version> 
    <Profile id="PlaceHolder"> 
    <title>Tailoring for py_test</title> 
    <select idref="xccdf_rule_name" selected="true"/> 
</Profile> 
</Tailoring> 

並有以下sample_XML文件:

<Benchmark xmlns="http://checklists.nist.gov/xccdf/1.1" xmlns:xsi="www.w3.org/2001/XMLSchema-instance" id="SAP-HANA" resolved="1" xml:lang="en-US"> 
<status date="2016-03-17">draft</status> 
<title xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="en-US">Guide to the Secure Configuration of SAP HANA</title> 
<version>0.1.28</version> 

<Profile id="profile1"> 
    <title xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="en-US">text1</title> 
    <select idref="This is rule 1" selected="true"/> 
    <set-value idref="ssfs_master_key_timeout">20</set-value> 
</Profile> 

<Profile id="profile2"> 
    <title xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="en-US">text2</title> 
    <select idref="this is rule1" selected="true"/> 
    <select idref="this is rule1" selected="true"/> 
    <select idref="this is rule1" selected="true"/> 
</Profile> 
</Benchmark> 

我需要創建一個new_xml文件, template_XML文件的副本。 ,但希望sample_XML文件的「PROFILE2」標籤,以取代「佔位符」文件標記在new_xml文件。它是一種合併2 xml文件並創建一個新文件。 下面是我曾嘗試代碼:

function call(id){ 
    var template_XML = 'C:\\MyDrive\\template_XML'; 
    var new_xml = 'C:\\MyDrive\\new_xml'; 
    data = fs.readFileSync(template_XML).toString(); 
    data1 = fs.readFileSync(sample_XML).toString(); 
    etree = et.parse(data); 
    etree1 = et.parse(data1); 
    var profile = etree.find('./Profile'); // Getting the profile sub-element. 
    etree.getroot().remove(profile)   // Removing the sub-element. So that I can insert new profile from sample file 

    var profiles = etree1.findall('./Profile'); // Find the required profile. 
    for (var i = 0; i < profiles.length; i++) { 
     if(profiles[i].get('id') == 'profile2') 
      var tmppro = profiles[i]; 
    } 
    console.log(tmppro); 
    etree.insert(3,tmppro);  // insert it. Failing 

    var write = fs.openSync(new_xml, 'w'); 
    etree.write(write);      // write it. Failing 
} 

對於一個或其他原因,這個代碼是沒有的「etree.insert」和「etree.write」方面的工作

回答

1

最後我能使其與當前的lib工作。 請參閱我的意見:

'use strict'; 
 

 
const et = require('elementtree'); 
 
const path = require('path'); 
 
const fs = require('fs'); 
 

 
function populateXmlTemplate(id) { 
 
\t //Please use path.join to make it cross-platform 
 
\t var template_XML = path.join(__dirname, 'template.xml'); 
 
\t var sample_XML = path.join(__dirname, 'sample.xml'); 
 
\t var new_xml = path.join(__dirname, 'new.xml'); 
 

 
\t var data = fs.readFileSync(template_XML).toString(); 
 
\t var data1 = fs.readFileSync(sample_XML).toString(); 
 

 
\t var etree = et.parse(data); 
 
\t var etree1 = et.parse(data1); 
 

 
\t var root = etree.getroot(); 
 

 
\t var placeholder = root.find('./Profile'); 
 
\t root.remove(placeholder); 
 

 
\t var profiles = etree1.findall('./Profile'); // Find the required profile. 
 
\t for (var i = 0; i < profiles.length; i++) { 
 
\t \t //If I get it right, it shouldn't be hardcoded 
 
\t \t if (profiles[i].get('id') == id) { 
 
\t \t \t var tmppro = profiles[i]; 
 
\t \t } 
 
\t } 
 

 
\t //After you removed the placeholder the number of children decreased 
 
\t //So it should be 2, not 3. 
 
\t //Also etree doesn't have insert method, please call root.insert 
 
\t root.insert(2, tmppro); 
 

 
\t //You have been writing the document a bit incorrectly. 
 
\t var resultXml = etree.write(); 
 
\t fs.writeFileSync(new_xml, resultXml); 
 
} 
 

 
populateXmlTemplate('profile2'); 
 

 
module.exports = {populateXmlTemplate};

但你是正確的,文件是不是好。它幾乎沒有。所以大多數情況下我只是一直在debugging它看到可用的方法,也有一些tests在lib回購。

還有其他模塊可以與js一起使用。請看這answer

+0

非常感謝Antonio,WebStorm在編寫進一步的應用程序時會幫助我很多。事實上,我並沒有意識到nodejs應用程序的任何IDE。 populateXmlTemplate()拋出堆棧跟蹤下,但現在它的確定,我會通過在IDE中調試它來處理這種情況。 etree.write(); // TypeError:無法讀取未定義的屬性'iter' 看來我需要+15聲望來upvote答案,但我的upvote被注意到。 :) –

+0

嗨安東尼奧,任何想法,如果我可以複製評論也。例如,如果標籤包含註釋<! - 一些註釋 - >。 ETREE未將sample_XML配置文件中的註釋部分複製到new_xml文件中。 –