xmlxslt

xsl:apply-template on nodes filtered by external xml file


I don't know the words for what I want to achieve, so I will try to explain as best as I can. Feel free to redirect me to existing questions.

Say I have an XML file containing a list of classes (called index.xml):

<root>
  <classes>
    <class>
      <id>ClassA</id>
    </class>
    <class>
      <id>ClassB</id>
    </class>
    <class>
      <id>ClassC</id>
    </class>
  </classes>
</root>

And I have in another XML file some property details:

<root>
  <properties>
    <property>
      <name>MyPropertyA</name>
      <type>ClassA</type>
    </property>
    <property>
      <name>MyPropertyB</name>
      <type>ClassB</type>
    </property>
    <property>
      <name>MyPropertyE</name>
      <type>ClassE</type>
    </property>
  </properties>
</root>

I would like to have a selector for apply-templates on the properties only if their type is contained in the classes node-set of the index.xml file.

I think I need to reference index.xml using the document() function and use the key() function to lookup in the classes, but I don't seem to succeed in putting those pieces together to achieve my goal...

I tried something like that but it does not work:

<xsl:variable name="ClassLookup" select="document('index.xml')/classes"/>
<xsl:apply-template match="property[key(ClassLookup, ./type)]">

Any help is appreciated.

EDIT: I'm using Saxon HE 10.9 (XSLT 2.0)


Solution

  • Without a key, you would use <xsl:apply-template match="property[type = document('index.xml')/classes/class/id]">.

    Using a key with secondary documents is easy in XSLT 2 and later so first state which version you use to allow us to tell whether a key is easily usable.