1 <?xml version="1.0" encoding="utf-8"?> 2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 3 xmlns:template="http://www.boddie.org.uk/ns/xmltools/template" 4 xmlns:dyn="http://exslt.org/dynamic" 5 extension-element-prefixes="dyn" 6 version="1.0"> 7 8 <xsl:param name="database"/> 9 10 <xsl:template match="configuration"> 11 <xsl:copy> 12 <xsl:apply-templates select="@*"/> 13 <!-- Complete all multiple choice fields. --> 14 <details> 15 <xsl:call-template name="complete-element"> 16 <xsl:with-param name="found-element" select="details/base-system[1]"/> 17 <xsl:with-param name="element-name">base-system</xsl:with-param> 18 </xsl:call-template> 19 <xsl:call-template name="complete-element"> 20 <xsl:with-param name="found-element" select="details/cpu[1]"/> 21 <xsl:with-param name="control-element" select="details/base-system[1]"/> 22 <xsl:with-param name="element-name">cpu</xsl:with-param> 23 <xsl:with-param name="control-element-name">base-system</xsl:with-param> 24 <xsl:with-param name="control-attribute-name">cpu-socket</xsl:with-param> 25 </xsl:call-template> 26 </details> 27 <memory> 28 <xsl:for-each select="memory/memory-unit"> 29 <xsl:call-template name="complete-element"> 30 <xsl:with-param name="found-element" select="."/> 31 <xsl:with-param name="element-name">memory-unit</xsl:with-param> 32 </xsl:call-template> 33 </xsl:for-each> 34 </memory> 35 <hard-disks> 36 <xsl:for-each select="hard-disks/hard-disk"> 37 <xsl:call-template name="complete-element"> 38 <xsl:with-param name="found-element" select="."/> 39 <xsl:with-param name="control-element" select="/configuration/details/base-system[1]"/> 40 <xsl:with-param name="element-name">hard-disk</xsl:with-param> 41 <xsl:with-param name="control-element-name">base-system</xsl:with-param> 42 <xsl:with-param name="control-attribute-name">interface</xsl:with-param> 43 </xsl:call-template> 44 </xsl:for-each> 45 </hard-disks> 46 <storage> 47 <xsl:for-each select="storage/storage-unit"> 48 <xsl:call-template name="complete-element"> 49 <xsl:with-param name="found-element" select="."/> 50 <xsl:with-param name="element-name">storage-unit</xsl:with-param> 51 </xsl:call-template> 52 </xsl:for-each> 53 </storage> 54 <peripherals> 55 <xsl:call-template name="complete-element"> 56 <xsl:with-param name="found-element" select="peripherals/keyboard[1]"/> 57 <xsl:with-param name="element-name">keyboard</xsl:with-param> 58 </xsl:call-template> 59 <xsl:call-template name="complete-element"> 60 <xsl:with-param name="found-element" select="peripherals/mouse[1]"/> 61 <xsl:with-param name="element-name">mouse</xsl:with-param> 62 </xsl:call-template> 63 <xsl:call-template name="complete-element"> 64 <xsl:with-param name="found-element" select="peripherals/screen[1]"/> 65 <xsl:with-param name="element-name">screen</xsl:with-param> 66 </xsl:call-template> 67 </peripherals> 68 </xsl:copy> 69 </xsl:template> 70 71 <xsl:template name="complete-element"> 72 <!-- Input parameters. --> 73 <xsl:param name="found-element"/> 74 <xsl:param name="control-element"/> 75 <!-- Database parameters. --> 76 <xsl:param name="element-name"/> 77 <xsl:param name="control-element-name"/> 78 <xsl:param name="control-attribute-name"/> 79 <!-- Find the database entries. --> 80 <xsl:variable name="element-enum-name"><xsl:value-of select="$element-name"/>-enum</xsl:variable> 81 <xsl:variable name="control-element-enum-name"><xsl:value-of select="$control-element-name"/>-enum</xsl:variable> 82 <!-- Find whether the input values are set. --> 83 <xsl:variable name="has-set-values" select="$found-element[@value]"/> 84 <xsl:variable name="has-control-values" select="$control-element and $control-element[@value]"/> 85 <!-- Get the database element for the element being prepared. --> 86 <xsl:variable name="database-element" select="$database/database/*[local-name() = $element-name]"/> 87 <!-- Get the database element for the control element. --> 88 <xsl:variable name="database-control-element" select="$database/database/*[local-name() = $control-element-name]"/> 89 <!-- Get the database entries for the control element. --> 90 <xsl:variable name="control-enum-elements" select="$database-control-element/*[local-name() = $control-element-enum-name]"/> 91 <!-- Get the database entry for the control element, then get the control attribute value in that entry. --> 92 <xsl:variable name="other-control-value" select="$control-enum-elements[@value = $control-element/@value]/@*[local-name() = $control-attribute-name]"/> 93 <!-- Make the element with the different values. --> 94 <xsl:element name="{$element-name}"> 95 <!-- Find the entries in the database for the element being prepared. --> 96 <xsl:for-each select="$database-element/*[local-name() = $element-enum-name]"> 97 <!-- Remember the current node for future comparisons. --> 98 <xsl:variable name="enum-element" select="."/> 99 <!-- Find whether the current entry matches the input value. --> 100 <xsl:variable name="matching-element" select="$found-element[@value = $enum-element/@value]"/> 101 <!-- Get the control attribute value for the current entry. --> 102 <xsl:variable name="this-control-value" select="@*[local-name() = $control-attribute-name]"/> 103 <!-- Filter the entry out unless no control element was given, this entry has no control attribute value or... 104 if the control attribute value matches the one for the control element. --> 105 <xsl:if test="not($has-control-values) or not($this-control-value) or $this-control-value = $other-control-value"> 106 <!-- Copy the entry. --> 107 <xsl:copy> 108 <!-- Include all attributes except the price, adding the price only if the item is selected. --> 109 <xsl:apply-templates select="@*[local-name() != 'price']"/> 110 <!-- Find whether this item is selected. --> 111 <xsl:choose> 112 <!-- In the current field, the value attribute matches this value. --> 113 <xsl:when test="$matching-element"> 114 <xsl:attribute name="value-is-set">true</xsl:attribute> 115 <xsl:apply-templates select="@price"/> 116 </xsl:when> 117 <!-- This value is the first and no value attribute is specified. --> 118 <xsl:when test="not($has-set-values) and count($enum-element/preceding-sibling::*) = 0"> 119 <xsl:attribute name="value-is-set">true</xsl:attribute> 120 <xsl:apply-templates select="@price"/> 121 </xsl:when> 122 <xsl:otherwise/> 123 </xsl:choose> 124 </xsl:copy> 125 </xsl:if> 126 </xsl:for-each> 127 </xsl:element> 128 </xsl:template> 129 130 <!-- Replicate unknown elements. --> 131 132 <xsl:template match="@*|node()"> 133 <xsl:copy> 134 <xsl:apply-templates select="@*|node()"/> 135 </xsl:copy> 136 </xsl:template> 137 138 </xsl:stylesheet>