XSLT多否定匹配条件扩展咨询:现有模板匹配规则优化需求
Got it, let's tackle this. You want to expand your existing XSLT template's match condition to support filtering out multiple file extensions instead of just .cif. Here are a few practical, maintainable approaches depending on your XSLT version:
Approach 1: Explicit Multiple Conditions (XSLT 1.0+)
If you only have a small, fixed set of extensions to exclude, you can directly chain ends-with checks with or inside the not() predicate. This is straightforward and works across all XSLT versions:
<xsl:template match="DataObject[not(ends-with(@FileRef, '.cif') or ends-with(@FileRef, '.xyz') or ends-with(@FileRef, '.mol'))]" mode="compound_links"> <xsl:variable name="link" select="./@FileRef"/> <xsl:text> | </xsl:text> <a data-test="compound-data-file-link"> <xsl:attribute name="href" select="func:imgUrl('original', $link)"/> <xsl:apply-templates select="ancestor::DefinitionListEntry/Term" mode="markup"/> </a> </xsl:template>
How it works: The template will match any DataObject whose FileRef does not end with .cif, .xyz, or .mol. Add/remove ends-with clauses as needed for other extensions.
Approach 2: Reusable Extension List (XSLT 2.0+)
For a more scalable solution (great if you might add more extensions later), define a variable to hold your excluded extensions, then use a some expression to check against the list:
<!-- Define your excluded extensions in one place for easy updates --> <xsl:variable name="excluded-extensions" select="('.cif', '.xyz', '.mol', '.pdb')"/> <xsl:template match="DataObject[not(some $ext in $excluded-extensions satisfies ends-with(@FileRef, $ext))]" mode="compound_links"> <xsl:variable name="link" select="./@FileRef"/> <xsl:text> | </xsl:text> <a data-test="compound-data-file-link"> <xsl:attribute name="href" select="func:imgUrl('original', $link)"/> <xsl:apply-templates select="ancestor::DefinitionListEntry/Term" mode="markup"/> </a> </xsl:template>
Why this is better: No need to modify the match condition every time you add/remove an extension—just update the $excluded-extensions variable. This keeps your code DRY and easier to maintain.
Approach 3: XSLT 1.0 Fallback (No ends-with or some Support)
If you're stuck on XSLT 1.0 (which lacks ends-with and some), you can use a contains trick to simulate the multi-extension check:
<xsl:template match="DataObject[not(contains('.cif.xyz.mol.', concat('.', substring-after(@FileRef, '.'), '.')))]" mode="compound_links"> <xsl:variable name="link" select="./@FileRef"/> <xsl:text> | </xsl:text> <a data-test="compound-data-file-link"> <xsl:attribute name="href" select="func:imgUrl('original', $link)"/> <xsl:apply-templates select="ancestor::DefinitionListEntry/Term" mode="markup"/> </a> </xsl:template>
How it works: We wrap each excluded extension in dots (e.g., .cif.) and check if the file's extension (also wrapped in dots) exists in that string. This avoids false matches (like a file named mycif.txt being incorrectly excluded).
内容的提问来源于stack exchange,提问作者Ollie Williams

