2017-04-22 1 views
-1

J'essaie de faire défiler une chaîne XML avec une expression régulière afin de créer une chaîne significative à partir de celle-ci.Analyser un code XML dans une chaîne avec des parenthèses imbriquées

Le code XML représente une expression booléenne imbriquée. Je l'ai donc il va extraire les valeurs qui font partie des égalités, mais je ne peux pas comprendre comment obtenir les opérateurs AND/OR, ni les parenthèses qui sont nécessaires dans le résultat final.

C'est ce que le XML ressemble à:

<applic id="TCTO_709_PRE_ALL"> 
<displayText><simplePara>All Aircraft without Extended Range Capability</simplePara></displayText> 
<!--BEGIN OR--> 
<evaluate andOr="or"> 
<!-- (--> 
    <assert applicPropertyIdent="partno" applicPropertyType="prodattr" applicPropertyValues="UHK97000-15" /> 
<!--BEGIN AND--> 
<evaluate andOr="and">  
    <!-- (--> 
<!--BEGIN OR--> 
    <evaluate andOr="or"> 
    <!-- (--> 
     <assert applicPropertyIdent="partno" applicPropertyType="prodattr" applicPropertyValues="UHK97000-10" /> 
     <assert applicPropertyIdent="partno" applicPropertyType="prodattr" applicPropertyValues="UHK97000-12" /> 
    <!--) --> 
    </evaluate> 
<!--BEGIN OR--> 
    <evaluate andOr="or"> 
     <!-- (--> 
     <assert applicPropertyIdent="TCTO_1Q-9A-709" applicPropertyType="condition" applicPropertyValues="PRE" /> 
     <assert applicPropertyIdent="TCTO_1Q-9A-709" applicPropertyType="condition" applicPropertyValues="NOI" /> 
     <!--) --> 
    </evaluate> 
    <!--) --> 
    </evaluate> 
    <!--) --> 
</evaluate> 
</applic> 

Tous les <assert> éléments sont inclus dans ET ou OU <evaluate> éléments.

Ceci est le résultat souhaité pour que XML:

(partno="UHK97000-15" or ((partno="UHK97000-10" or partno="UHK97000-12") and (TCTO_1Q-9A-709="PRE" or TCTO_1Q-9A-709="NOI"))) 

Voici mon script que j'essaie avec:

var sApplic = '<applic id="TCTO_709_PRE_ALL"><displayText><simplePara>All Aircraft without Extended Range Capability</simplePara></displayText><evaluate andOr="or"><assert applicPropertyIdent="partno" applicPropertyType="prodattr" applicPropertyValues="UHK97000-15"></assert><evaluate andOr="and"><evaluate andOr="or"><assert applicPropertyIdent="partno" applicPropertyType="prodattr" applicPropertyValues="UHK97000-10"></assert><assert applicPropertyIdent="partno" applicPropertyType="prodattr" applicPropertyValues="UHK97000-12"></assert></evaluate><evaluate andOr="or"><assert applicPropertyIdent="TCTO_1Q-9A-709" applicPropertyType="condition" applicPropertyValues="PRE"></assert><assert applicPropertyIdent="TCTO_1Q-9A-709" applicPropertyType="condition" applicPropertyValues="NOI"></assert></evaluate></evaluate></evaluate></applic>'; 
var sRegXEval = /<assert applicPropertyIdent="(.*?)" applicPropertyType=".*?" applicPropertyValues=(".*?")(\/>|<\/assert>)?/g; 
var sMatch = sRegXEval.exec(sApplic); 
while (sMatch != null) { 
     var sFirst = sMatch[1] + "=" + sMatch[2]; 
      document.write("<p>sMatch[" + i +"]" + sFirst); 
    sMatch = sRegXEval.exec(sApplic); 
    i++; 
} 
</script> 

Voici les résultats de ce script, qui sont encore loin de la résultat souhaité:

sMatch[0]partno="UHK97000-15" 
sMatch[1]partno="UHK97000-10" 
sMatch[2]partno="UHK97000-12" 
sMatch[3]TCTO_1Q-9A-709="PRE" 
sMatch[4]TCTO_1Q-9A-709="NOI" 

Comment puis-je améliorer le code pour obtenir le résultat souhaité?

MIS À JOUR La chaîne XML a changé à

var sApplic = '<datamodule><file>CClasic.sgm</file><applic><displayText><simplePara>Cooking Classics</simplePara></displayText><assert applicPropertyIdent="author" applicPropertyType="prodattr" applicPropertyValues="Crocker"/></applic></datamodule>'; 

Depuis que je l'ai fait le code @trincot m'a donné ne fonctionne plus. Comment améliorer le script à prendre dans cette nouvelle chaîne et me permettre d'afficher également le nom du fichier dans l'élément?

+0

S'il vous plaît essayer d'être plus clair quand poser des questions ici. Qu'est-ce que les résultats de la formule? Quel est le sujet du test? Vous n'avez même pas écrit la sortie désirée. Je déteste quand quelqu'un veut vraiment de l'aide, mais ne parvient pas à le demander correctement. Lire [ici] (https://stackoverflow.com/help/mcve) – bugwheels94

+0

J'ai supprimé mes réponses et j'ai modifié ma première question pour mieux clarifier les choses. Merci pour l'information. –

+0

Les valeurs que j'extrempe sont applicPropertyIdent = "VALUE1" applicPropertyValues ​​= "VALUE2" Le tableau les extrait du script avec l'expression régulière. Ce qui me pose problème, c'est d'ajouter les parenthèses avant et après les éléments . Ce qui est particulièrement difficile, c'est que vous devez ajouter (OR/AND) après la valeur trouvée par les tableaux. Par exemple (partno = "PRE" ou .C'est ce que je n'arrive pas à comprendre quoi faire.) –

Répondre

0

Vous ne devriez pas essayer d'analyser XML avec des expressions régulières: elles ne sont pas bien adaptées à une telle tâche.

Utilisez plutôt la DOM parser that the Web API offers in all major browsers, et une fonction récursive qui prendra soin d'insérer les opérateurs booléens et les parenthèses:

function parse(node) { 
 
    return Array.from(node.children, child => 
 
     child.tagName === 'assert' 
 
      ? child.getAttribute('applicPropertyIdent') 
 
       + '="' + child.getAttribute('applicPropertyValues') + '"' 
 
      : child.tagName === 'evaluate' 
 
       ? '(' + parse(child) + ')' 
 
       : parse(child) 
 
    ).filter(Boolean).join(' ' + node.getAttribute('andOr') + ' '); 
 
} 
 

 
const sApplic = `<datamodule> 
 
<file>CClasic.sgm</file> 
 
<applic id="TCTO_709_PRE_ALL"> 
 
    <displayText> 
 
     <simplePara>All Aircraft without Extended Range Capability</simplePara> 
 
    </displayText> 
 
    <evaluate andOr="or"> 
 
     <assert applicPropertyIdent="partno" applicPropertyType="prodattr" applicPropertyValues="UHK97000-15"></assert> 
 
     <evaluate andOr="and"> 
 
      <evaluate andOr="or"> 
 
       <assert applicPropertyIdent="partno" applicPropertyType="prodattr" applicPropertyValues="UHK97000-10"></assert> 
 
       <assert applicPropertyIdent="partno" applicPropertyType="prodattr" applicPropertyValues="UHK97000-12"></assert> 
 
      </evaluate> 
 
      <evaluate andOr="or"> 
 
       <assert applicPropertyIdent="TCTO_1Q-9A-709" applicPropertyType="condition" applicPropertyValues="PRE"></assert> 
 
       <assert applicPropertyIdent="TCTO_1Q-9A-709" applicPropertyType="condition" applicPropertyValues="NOI"></assert> 
 
      </evaluate> 
 
     </evaluate> 
 
    </evaluate> 
 
    </applic> 
 
</datamodule>`; 
 

 
const xml = (new window.DOMParser()).parseFromString(sApplic, "text/xml"); 
 
const result = parse(xml.documentElement); 
 
console.log(result);

+0

C'est tellement incroyable, merci Le problème est que je cours cela sur dix mille documents, donc je dois être C'est la seule partie du script, j'ai l'habitude d'utiliser un éditeur de texte (UltraEditStudio) et non l'analyseur DOM.Pendant un certain temps, j'ai utilisé XSLT mais cette compétence a disparu à mesure que les délais de travail sont devenus persistants. –

+0

Si cette réponse correspond à vos besoins, veuillez [marquer la réponse comme acceptée] (http://stackoverflow.com/help/someone-answers). – trincot

+0

J'avais besoin de développer ma chaîne XML pour inclure le nom du fichier et maintenant je dois l'extraire, l'identifiant de l'application et les valeurs de simplePara. –