2017-04-22 53 views
-1

我試圖通過正則表達式的XML字符串循環,以便從中構建一個有意義的字符串。使用嵌套括號將XML解析爲字符串

XML表示嵌套的布爾表達式。

我有它,所以它會提取屬於平等的一部分的值,但我不知道如何獲得AND/OR運算符,也不知道最終結果中需要的括號。

這是XML的樣子:

<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> 

所有<assert>元素包含在AND或OR <evaluate>元素。

這對於XML期望的結果:

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> 

下面是腳本的結果,這仍遠:

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

這裏是我的腳本我有嘗試想要的結果:

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" 

我該如何改進代碼才能得到想要的結果?

更新 因爲我做這個@trincot給了我不再工作代碼的XML字符串已更改爲

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

。如何改進腳本以接收這個新字符串,並允許我在元素中顯示文件名?

+0

請嘗試在這裏提問的時候更清晰。公式結果是什麼?什麼是測試主題?你甚至沒有寫出所需的輸出。當有人真的需要幫助但沒有正確地要求時,我討厭它。閱讀[這裏](https://stackoverflow.com/help/mcve) – bugwheels94

+0

我刪除了我的答案,並修改我的第一個問題,希望更好地澄清事情。感謝您的信息。 –

+0

我提取的值是 applicPropertyIdent =「VALUE1」 applicPropertyValues =「VALUE2」 數組將它們拉到腳本中,並使用正則表達式。我遇到的問題是在元素之前和之後添加了括號。特別棘手的是你必須在數組找到值之後添加(OR/AND)「。例如(partno =「PRE」或。這就是我不知道該怎麼辦 –

回答

0

你不應該試圖用正則表達式來解析XML:它們不適合這樣的任務。

而是使用DOM parser that the Web API offers in all major browsers,這將插入布爾運算符和括號的護理遞歸函數:

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

這是如此令人難以置信,謝謝。乞求的事情是我在萬文件上運行這個,所以我需要能夠在如此大的範圍內運行它,而這是腳本的唯一部分,我習慣於使用文本編輯器(UltraEditStudio)而不是DOM解析器。有一段時間我使用XSLT,但隨着工作截止日期的持續,這項技能消失了。 –

+0

如果此答案符合您的需求,請[將答案標記爲已接受](http://stackoverflow.com/help/someone-answers)。 – trincot

+0

我需要擴展我的XML字符串以包含文件名,現在必須提取它,應用程序ID和simplePara值。 –