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



>我有这个:

<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,':') 仅使用值为 ABCDE123/1:R1 的 MY RULES,而不使用其他规则。我被困住了,我不知道我错在哪里。

知道为什么这只首先使用我的规则而不是全部吗?

假设您可以使用 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()来比较匹配的元素和其他元素子字符串:

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

最新更新