2017-04-22 219 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值。 –