Search code examples
xmlxsltselectapply-templates

XSL: How to limit the select in apply-templates based on a separate XML element


Here is an example of what I am trying to do. XML:

<TEST>
  <NODE>
    <A id="ELEMENT_1"/>
    <A id="ELEMENT_2"/>
    <A id="ELEMENT_3"/>
  </NODE>
  <SOME_OTHER_NODE>
    <B nodeId="ELEMENT_1" invalid="1"/>
  </SOME_OTHER_NODE>
</TEST>

XSL:

<xsl:apply-templates select="A[?? only select the A's where there is no B where A/@id = B/@nodeId and B/@invalid = 1 ??]"/>

Is this even possible? In the actual xsl I have something like this currently:

<xsl:apply-templates select="(ANSWER|GROUP)[position() mod 2 = 0]"/>

And I want to find a way to limit the ANSWER's selected based upon a different element in the xml. Hopefully I have clearly explained this, let me know if I have not. Perhaps there is a better way of doing something like this. I am open to any feedback or suggestions. Thanks.


Solution

  • This XPath expression (node set comparison) with NODE as context:

    A[not(@id = ../../SOME_OTHER_NODE/B[@invalid='1']/@nodeId)]
    

    With keys:

    <xsl:key name="kInvalidTest" match="B[@invalid=1]" use="@nodeId"/>
    ...
    <xsl:appy-templates select="A[not(key('kInvalidTest',@id))]"/>