查找具有带属性的子节点作为其他节点组的所有节点

时间:2017-10-30 16:13:38

标签: xslt

我有这个:

<SOLUTION> 
<CONFIGURATION>  
 <INST NR="1">  
  <CSTICS>  
   <CSTIC CHARC="SOME_TXT1" VALUE="GLOBAL1"/>  
   <CSTIC CHARC="SOME_TXT2" VALUE="GLOBAL2"/>  
   <CSTIC CHARC="MY_RULES" VALUE="ABCDE123/1:R1"/>  
   <CSTIC CHARC="MY_RULES" VALUE="FGH112/1:R1"/>  
   <CSTIC CHARC="MY_RULES" VALUE="IJKL/5:R1"/>
   <CSTIC CHARC="SOME_TEXT3" VALUE="GLOBAL3"/> 
  </CSTICS>
 </INST>
 <PARTS>
  <INST NR="2">
   <CSTICS>
    <CSTIC CHARC="SOME_TEXT2_4" VALUE="GLOBAL3"/>
    <CSTIC CHARC="SOME_TEXT2_5" VALUE="GLOBAL3"/>
   </CSTICS>
  </INST>
  <INST NR="3">
   <CSTICS>
    <CSTIC CHARC="SOME_TEXT3_4" VALUE="GLOBAL3"/>
    <CSTIC CHARC="SOME_TEXT3_5" VALUE="GLOBAL3"/>
   </CSTICS>
  </INST>
  <INST NR="4">
   <CSTICS>
    <CSTIC CHARC="SOME_TEXT4_4" VALUE="GLOBAL3"/>
    <CSTIC CHARC="RULE" VALUE="ABCDE123/1"/>
   </CSTICS>
  </INST> 
  <INST NR="5">
   <CSTICS>
    <CSTIC CHARC="SOME_TEXT5_4" VALUE="GLOBAL3"/>
    <CSTIC CHARC="RULE" VALUE="ABCDE123/1"/>
   </CSTICS>
  </INST> 
  <INST NR="6">
   <CSTICS>
    <CSTIC CHARC="SOME_TEXT6_4" VALUE="GLOBAL3"/>
    <CSTIC CHARC="RULE" VALUE="FGH112/1"/>
   </CSTICS>
  </INST>
  <INST NR="7">
   <CSTICS>
    <CSTIC CHARC="SOME_TEXT7_4" VALUE="GLOBAL3"/>
    <CSTIC CHARC="RULE" VALUE="ABCDE123/1"/>
   </CSTICS>
  </INST>
  <INST NR="8">
   <CSTICS>
    <CSTIC CHARC="SOME_TEXT8_4" VALUE="GLOBAL3"/>
    <CSTIC CHARC="SOME_TEXT8_5" VALUE="GLOBAL3"/>
   </CSTICS>
  </INST> 
  <INST NR="9">
   <CSTICS>
    <CSTIC CHARC="SOME_TEXT9_4" VALUE="GLOBAL3"/>
    <CSTIC CHARC="RULE" VALUE="IJKL/5"/>
    <CSTIC CHARC="SOME_TEXT9_5" VALUE="GLOBAL3"/>
   </CSTICS>
  </INST>
 </PARTS>
</CONFIGURATION> 
</SOLUTION> 

我想要这个:

<OBJ NAME="4">
 <EL NAME="SOME_TEXT4_4"/>
</OBJ>
<OBJ NAME="5">
 <EL NAME="SOME_TEXT5_4"/>
</OBJ>
<OBJ NAME="6">
 <EL NAME="SOME_TEXT6_4"/>
</OBJ>
<OBJ NAME="7">
 <EL NAME="SOME_TEXT7_4"/>
</OBJ>
<OBJ NAME="9">
 <EL NAME="SOME_TEXT9_4"/>
 <EL NAME="SOME_TEXT9_5"/>
</OBJ>

我这样做:

<xsl:template match="//INST[./CSTICS/CSTIC[@CHARC='RULE']/@VALUE=substring-before(/SOLUTION/CONFIGURATION/INST/CSTICS/CSTIC[@CHARC='MY_RULES']/@VALUE,':')]">
   <OBJ NAME="@NR">
     <xsl:for-each select="./CSTICS/CSTIC[starts-with(@CHARC,'SOME_TEXT')]">
      <EL NAME="@CHARC"/>
     </xsl:for-each>
   </OBJ>

    

但是,我明白了:

<OBJ NAME="4">
 <EL NAME="SOME_TEXT4_4"/>
</OBJ>
<OBJ NAME="5">
 <EL NAME="SOME_TEXT5_4"/>
</OBJ>
<OBJ NAME="7">
 <EL NAME="SOME_TEXT7_4"/>
</OBJ>

由于 = substring-before(/ SOLUTION / CONFIGURATION / INST / CSTICS / CSTIC [@ CHARC ='MY_RULES'] / @ VALUE,':')仅使用值为<的第一个MY RULES strong> ABCDE123 / 1:R1 而不是其他人。 我被困住了,我不知道我错在哪里。

有没有想过为什么这只使用第一个我的规则而不是所有的?

1 个答案:

答案 0 :(得分:1)

假设您可以使用XSLT 2.0,您可以将substring-before调用移动到路径表达式的最后一步:

<xsl:template match="INST[CSTICS/CSTIC[@CHARC='RULE']/@VALUE = /SOLUTION/CONFIGURATION/INST/CSTICS/CSTIC[@CHARC='MY_RULES']/substring-before(@VALUE,':')]">
    <OBJ NAME="{@NR}">
        <xsl:for-each select="CSTICS/CSTIC[starts-with(@CHARC,'SOME_TEXT')]">
            <EL NAME="{@CHARC}"/>
        </xsl:for-each>
    </OBJ>
</xsl:template>

使用XSLT 1.0,我认为您需要将检查移动到xsl:if,因为您可以使用current()来比较匹配的元素和其他元素substring-before:

<xsl:template match="INST">
    <xsl:if test="/SOLUTION/CONFIGURATION/INST/CSTICS/CSTIC[@CHARC='MY_RULES'][substring-before(@VALUE,':') = current()/CSTICS/CSTIC[@CHARC='RULE']/@VALUE]">
        <OBJ NAME="{@NR}">
            <xsl:for-each select="CSTICS/CSTIC[starts-with(@CHARC, 'SOME_TEXT')]">
                <EL NAME="{@CHARC}"/>
            </xsl:for-each>
        </OBJ>
    </xsl:if>
</xsl:template>