I am trying to write an XSLT "X_start" that constructs another XSLT "X_generated" from an xml file containing rules. My problem is to create a sequence for comparisons beween what I come across in the xml file and what I've generated in X_generated. The idea is to do this comparison, and if this doesn't match I will generate some text. In my examples I am comparing if I actually can find the value, because if I try to see if the value is outside the allowed values, I will always succeed unfortunately.
The attribute value "conditional" means that if the template matches, then the used value must be according to some set of values.
Any help/hint is appreciated, and let me know if you want me to clarify something.
Example on rules:
<?xml version="1.0" encoding="UTF-8"?>
<rules>
<rule type="conditional">
<xPath>//elemA/@attribute1</xPath>
<val allow="A"/>
<val allow="B"/>
</rule>
<rule type="conditional">
<xPath>//elemC/@attribute1</xPath>
<val allow="C"/>
<val allow="D"/>
</rule>
<rule type="conditional">
<xPath>//elemB</xPath>
<val allow="one"/>
<val allow="two"/>
<val allow="three"/>
</rule>
</rules>
My current draft XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias"
version="3.0">
<xsl:output method="xml" indent="true" encoding="UTF-8"/>
<xsl:mode on-no-match="shallow-skip"/>
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:template match="/">
<axsl:stylesheet>
<xsl:attribute name="expand-text" select="'true'"/>
<xsl:attribute name="version" select="'3.0'"/>
<xsl:apply-templates select="rules/*"/>
</axsl:stylesheet>
</xsl:template>
<xsl:template match="rule">
<!-- This creates ("A", "B") -->
<xsl:variable name="vals_from_for_each" as="xs:string*">
<xsl:for-each select="val/@allow">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:variable>
<!-- This also creates ("A", "B") -->
<xsl:variable name="vals_from_seq_text" as="xs:string*">
<xsl:sequence select="val/@allow"/>
</xsl:variable>
<axsl:template>
<xsl:attribute name="match" select="xPath"/>
<!-- Attempt to move the sequence into the generated template -->
<axsl:variable name="vals" as="xs:string*">
<!-- But this generates "A B", and is therefore not valid for comparison.
I cannot compare a value like ". = A B", it needs to be ". = ('A', 'B')-->
<xsl:sequence select="$vals_from_seq_text"/>
</axsl:variable>
<axsl:if test=". = $vals">
<axsl:message>Success</axsl:message>
</axsl:if>
<!-- trying by building a comparison tree (that doesn't work either... -->
<axsl:variable name="value_list" as="element()*">
<root>
<xsl:for-each select="val/@allow">
<val><xsl:value-of select="."/></val>
</xsl:for-each>
</root>
</axsl:variable>
<axsl:if test=". = $value_list/root/val">
<axsl:message>Found in tree - Success</axsl:message>
</axsl:if>
</axsl:template>
</xsl:template>
Resulting XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
expand-text="true"
version="3.0">
<xsl:template match="//elemA/@attribute1">
<xsl:variable name="vals" as="xs:string*">A B</xsl:variable>
<xsl:if test=". = $vals">
<xsl:message>Success</xsl:message>
</xsl:if>
<xsl:variable name="value_list" as="element()*">
<root>
<val>A</val>
<val>B</val>
</root>
</xsl:variable>
<xsl:if test=". = $value_list/root/val">
<xsl:message>Found in tree - Success</xsl:message>
</xsl:if>
</xsl:template>
<xsl:template match="//elemC/@attribute1">
<xsl:variable name="vals" as="xs:string*">C D</xsl:variable>
<xsl:if test=". = $vals">
<xsl:message>Success</xsl:message>
</xsl:if>
<xsl:variable name="value_list" as="element()*">
<root>
<val>C</val>
<val>D</val>
</root>
</xsl:variable>
<xsl:if test=". = $value_list/root/val">
<xsl:message>Found in tree - Success</xsl:message>
</xsl:if>
</xsl:template>
<xsl:template match="//elemB">
<xsl:variable name="vals" as="xs:string*">one two three</xsl:variable>
<xsl:if test=". = $vals">
<xsl:message>Success</xsl:message>
</xsl:if>
<xsl:variable name="value_list" as="element()*">
<root>
<val>one</val>
<val>two</val>
<val>three</val>
</root>
</xsl:variable>
<xsl:if test=". = $value_list/root/val">
<xsl:message>Found in tree - Success</xsl:message>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
So none of the messages triggers, I fail in creating some comparable thing in my resulting XSLT. Any created sequence is created as separate values in a string(?), and I cannot do a lookup in the generated tree segment (which I guessed wouldn't work, but desperate as one can be, I tried anyway). While writing this, I started thinking that one way could be to use a separate mode where I could create a completely separate xml document with lookup values, but this seems a bit worse than creating a lookup within each template. So, any ideas on how I can transfer my allowed values from my source XML to the generated XSLT?