2017-03-02 1 views
0

J'ai une question sur le même module que j'ai posté la dernière fois dans le message ci-dessous. On dirait qu'il est assez difficile de traiter l'analyse XML. Avec elementTree ayant une documentation très mearge.nodejs elementtree npm xml analyse et fusion

Je dispose d'un fichier ci-dessous de 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> 

Et un fichier ci-dessous de 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> 

Je dois créer un fichier new_xml, une copie de fichier template_XML. Mais veulent remplacer "PlaceHolder" tag profil dans fichier new_xml avec le tag "profile2" de fichier sample_XML. C'est une sorte de fusion de 2 fichiers XML et en créer un nouveau. Voici le code que j'ai essayé:

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 
} 

Pour l'une ou l'autre raison, ce code ne fonctionne pas en termes de « etree.insert » et « etree.write »

Répondre

1

Enfin j'ai pu pour le faire fonctionner avec lib actuelle. S'il vous plaît Voir mes commentaires:

'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};

Mais vous avez raison, la documentation est pas bon. C'est surtout manquant. Donc, la plupart du temps j'ai simplement été debugging pour voir les méthodes disponibles, aussi il y a quelques tests dans le repo lib.

Il existe d'autres modules pour travailler avec js. S'il vous plaît voir ce answer.

+0

Merci beaucoup Antonio, WebStorm m'aidera beaucoup à écrire d'autres applications. En fait, je ne connaissais aucun IDE pour l'application nodejs. populateXmlTemplate() lance en dessous de la trace de la pile, mais maintenant c'est OK, je vais gérer la situation en le déboguant dans IDE. etree.write(); // TypeError: Impossible de lire la propriété 'iter' de undefined Il semble que j'ai besoin de + 15reputation pour afficher une réponse, mais mon upvote est noté. :) –

+0

Salut Antonio, aucune idée si je peux copier le commentaire aussi. Par exemple, si la balise contient des commentaires . ETREE ne copie pas la section des commentaires du profil sample_XML dans le fichier new_xml. –