问题
I have a question on same module as I posted last time in below post. Seems like, it is quite difficult to deal with XML parsing. With elementTree having very mearge documentation.
I have a below template_XML file:
<?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>
And a below sample_XML file:
<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>
I need to create a new_xml file, a copy of template_XML file. But want to replace "PlaceHolder" profile tag in new_xml file with the "profile2" tag of sample_XML file. Its a kind of merging of 2 xml file and creating a new one. Below is the code I have tried:
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
}
For one or the other reason, this code is not working in terms of "etree.insert" and "etree.write"
回答1:
Finally I was able to make it working with current lib. Please see my comments:
'use strict';
const et = require('elementtree');
const path = require('path');
const fs = require('fs');
function populateXmlTemplate(id) {
//Please use path.join to make it cross-platform
var template_XML = path.join(__dirname, 'template.xml');
var sample_XML = path.join(__dirname, 'sample.xml');
var new_xml = path.join(__dirname, 'new.xml');
var data = fs.readFileSync(template_XML).toString();
var data1 = fs.readFileSync(sample_XML).toString();
var etree = et.parse(data);
var etree1 = et.parse(data1);
var root = etree.getroot();
var placeholder = root.find('./Profile');
root.remove(placeholder);
var profiles = etree1.findall('./Profile'); // Find the required profile.
for (var i = 0; i < profiles.length; i++) {
//If I get it right, it shouldn't be hardcoded
if (profiles[i].get('id') == id) {
var tmppro = profiles[i];
}
}
//After you removed the placeholder the number of children decreased
//So it should be 2, not 3.
//Also etree doesn't have insert method, please call root.insert
root.insert(2, tmppro);
//You have been writing the document a bit incorrectly.
var resultXml = etree.write();
fs.writeFileSync(new_xml, resultXml);
}
populateXmlTemplate('profile2');
module.exports = {populateXmlTemplate};
But you're right, the documentation is not good. It's mostly missing. So mostly I simply have been debugging it to see the available methods, also there are some tests in the lib repo.
There are other modules to work with js. Please see this answer.
来源:https://stackoverflow.com/questions/42553153/nodejs-elementtree-npm-xml-parsing-and-merging