BeerXML

BeerXML is an open data standard used to exchange recipes and related beer brewing information. There are websites and mobile apps that support the standard. There are development packages available for a variety of software platforms and programming languages. It’s used by professionals to automate processes, and by hobbyists to share favorites. In short, it’s easy to find and/or create recipes in BeerXML format .

Displaying recipes within WordPress, then, is simply a matter of creating an XSL stylesheet to read and transform recipes from XML to HTML. The sample stylesheet here – beer.xsl – reads the input file, and creates a framework for detailed customization of the output later. For reference, required nodes are starred (eg, *NAME); optional nodes are omitted if empty; and display-only, extension nodes are prefixed with plus marks (eg, +DISPLAY_AMOUNT).

Note the use of <xsl:call-template name="util-super-global"> at the top of beer.xsl. A single XML data file can contain multiple recipes, so we are using the util-super-global template from plugins/xslt-processor/xsl/util.xsl to check PHP’s global _REQUEST array for the requested recipe number (eg, ?recipe=2). That allows switching between the recipes.


Version 1

[xslt_transform_xml xsl="case-study-beer/beer.xsl" xml="case-study-beer/four-recipes.xml" /]
Output v1:

Wit

*NAME Wit
*VERSION 1
*TYPE All Grain
*BREWER Brad Smith
*BATCH_SIZE 19.68425500
*BOIL_SIZE 19.68425500
*BOIL_TIME 60
*EFFICIENCY 75.0
DATE 4/17/2003
NOTES Many thanks to Jay Russ for starting me on Wit – and providing some starter recipes from which this one eventually evolved!

*NAME Witbier
*VERSION 1
*CATEGORY Belgian & French Ale
*CATEGORY_NUMBER 1
*STYLE_LETTER A
*STYLE_GUIDE BJCP 1999
*TYPE Ale
*OG_MIN 1.04400000
*OG_MAX 1.05500000
*FG_MIN 1.00800000
*FG_MAX 1.01200000
*IBU_MIN 15.0
*IBU_MAX 25.0
*COLOR_MIN 2.00000000
*COLOR_MAX 4.00000000
CARB_MIN 2.1
CARB_MAX 2.7>
ABV_MIN 4.1
ABV_MAX 5.5
PROFILE Light to medium body. Unmalted wheat adds body and disctinctive flavor. Large white head. Low hop bitterness and flavor. Pale yellow color. Moderate carbonation. Some chill haze is OK.
INGREDIENTS Belgian pale malt. Up to 50% unmalted wheat (torrified or flaked often used). 5-10% flaked or rolled oats. Noble hops (Hallertauer or Saaz). Wit yeast. Curaco bitter orange peel and coriander. Soft water.
EXAMPLES Celis White, Wieckse Witte
NOTES Distinctive Wit or “White” beer spiced with bitter Curacao orange peel and coriander. A distinctive yeast strain provides orange aroma/flavor.
+DISPLAY_OG_MIN 1.044 SG
+DISPLAY_OG_MAX 1.055 SG
+DISPLAY_FG_MIN 1.008 SG
+DISPLAY_FG_MAX 1.012 SG
+DISPLAY_COLOR_MIN 2.0 SRM
+DISPLAY_COLOR_MAX 4.0 SRM
+OG_RANGE 1.044-1.055 SG
+FG_RANGE 1.008-1.012 SG
+IBU_RANGE 15.0-25.0 IBU
+CARB_RANGE 2.1-2.7 vols
+COLOR_RANGE 2.0-4.0 SRM
+ABV_RANGE 4.1-5.5 %

*NAME Brew Pot (6+gal) and Igloo/Gott Cooler (5 Gal)
*VERSION 1
*BOIL_SIZE 22.70566900
*BATCH_SIZE 18.927168
TUN_VOLUME 18.92716800
TUN_WEIGHT 1.814368
TUN_SPECIFIC_HEAT 0.300
TOP_UP_WATER 0.00000000
TRUB_CHILLER_LOSS 0.94635800
EVAP_RATE 9.0
BOIL_TIME 60.0
CALC_BOIL_VOLUME FALSE
LAUTER_DEADSPACE 0.94635800
TOP_UP_KETTLE 0.00000000
HOP_UTILIZATION 100.0
NOTES Popular all grain setup. 5 Gallon Gott or Igloo cooler as mash tun with false bottom, and 7-9 gallon brewpot capable of boiling at least 6 gallons of wort. Primarily used for single infusion mashes.
+DISPLAY_BOIL_SIZE 6.00 gal
+DISPLAY_BATCH_SIZE 5.00 gal
+DISPLAY_TUN_VOLUME 5.00 gal
+DISPLAY_TUN_WEIGHT 4.00 lb
+DISPLAY_TOP_UP_WATER 0.00 gal
+DISPLAY_TRUB_CHILLER_LOSS 0.25 gal
+DISPLAY_LAUTER_DEADSPACE 0.25 gal
+DISPLAY_TOP_UP_KETTLE 0.00 gal

HOP 1
*NAME Goldings, East Kent
*VERSION 1
*ALPHA 5.00
*AMOUNT 0.0283500
*USE Boil
*TIME 60.000
TYPE Aroma
FORM Pellet
BETA 3.50
HSI 35.0
ORIGIN United Kingdom
NOTES Used For: General purpose hops for bittering/finishing all British Ales Aroma: Floral, aromatic, earthy, slightly sweet spicy flavor Substitutes: Fuggles, BC Goldings Examples: Bass Pale Ale, Fullers ESB, Samual Smith’s Pale Ale
+DISPLAY_AMOUNT 1.00 oz
+INVENTORY 1.00 oz
+DISPLAY_TIME 60 min

FERMENTABLE 1
*NAME Pale Malt (2 Row) Bel
*VERSION 1
*TYPE Grain
*AMOUNT 2.041164
*YIELD 80.0
COLOR 3.2
ADD_AFTER_BOIL FALSE
ORIGIN Belgium
COARSE_FINE_DIFF 1.5
MOISTURE 4.0
DIASTATIC_POWER 60.0
PROTEIN 10.5
MAX_IN_BATCH 100.0
RECOMMEND_MASH FALSE
IBU_GAL_PER_LB 0.000
NOTES Base malt for all beer styles Higher potential yield than US, English equivalent pale ale malts
+DISPLAY_AMOUNT 4.50 lb
+POTENTIAL 1.037
+INVENTORY 4.50 lb
+DISPLAY_COLOR 3.2 SRM
FERMENTABLE 2
*NAME Wheat, Flaked
*VERSION 1
*TYPE Grain
*AMOUNT 2.041164
*YIELD 77.0
COLOR 1.6
ADD_AFTER_BOIL FALSE
ORIGIN US
COARSE_FINE_DIFF 1.5
MOISTURE 9.0
DIASTATIC_POWER 0.0
PROTEIN 16.0
MAX_IN_BATCH 40.0
RECOMMEND_MASH TRUE
IBU_GAL_PER_LB 0.000
NOTES Flaked wheat adds to increased body and foam retention Used in place of raw or torrified wheat for faster conversion and better yield. May be used in small amounts to improve head retention and body Examples: Belgian White beer, Wit
+DISPLAY_AMOUNT 4.50 lb
+POTENTIAL 1.035
+INVENTORY 4.50 lb
+DISPLAY_COLOR 1.6 SRM

MISC 1
*NAME Coriander Seed
*VERSION 1
*TYPE Spice
*USE Boil
*TIME 5.000
*AMOUNT 0.022180
AMOUNT_IS_WEIGHT FALSE
USE_FOR Belgian Wit
NOTES Used in Belgian Wit, Whites, and Holiday ales. Very good when used in light wheat ales. Often used with Bitter Orange Peel.
+DISPLAY_AMOUNT 0.75 oz
+INVENTORY 0.00 oz
+DISPLAY_TIME 5.0 min
MISC 2
*NAME Orange Peel, Bitter
*VERSION 1
*TYPE Spice
*USE Boil
*TIME 5.000
*AMOUNT 0.022180
AMOUNT_IS_WEIGHT FALSE
USE_FOR Belgian Wit
NOTES Made from the Curaco Orange Peel, peels are green-gray in color. Used to add a distinctive flavor to Belgian Wits and White beers.
+DISPLAY_AMOUNT 0.75 oz
+INVENTORY 0.00 oz
+DISPLAY_TIME 5.0 min

YEAST 1
*NAME Belgian Wit Ale
*VERSION 1
*TYPE Wheat
*FORM Liquid
*AMOUNT 0.0350130
AMOUNT_IS_WEIGHT FALSE
LABORATORY White Labs
PRODUCT_ID WLP400
MIN_TEMPERATURE 19.4444
MAX_TEMPERATURE 23.3333
FLOCCULATION Low
ATTENUATION 76.0
BEST_FOR Belgian Wit
TIMES_CULTURED 0
MAX_REUSE 5
ADD_TO_SECONDARY FALSE
NOTES Phenolic and tart. The original yeast used to produce Wit in Belgium.
+DISPLAY_AMOUNT 35 ml
+DISP_MIN_TEMP 67.0 F
+DISP_MAX_TEMP 74.0 F
+INVENTORY 0 Pkgs
+CULTURE_DATE 7/6/2003

*NAME Single Infusion, Medium Body
*VERSION 1
*GRAIN_TEMP 22.22222200
*MASH_STEPS Mash In 1 Infusion 10.646532 60 67.77777800 2 67.77777800 Add 11.25 qt of water at 165.9 F 1.25 0.00 qt 165.9 F DISPLAY_STEP_TEMP 11.25 qt Mash Out 1 Infusion 5.962058 10 75.55555600 2 75.55555600 Add 6.30 qt of water at 196.6 F 1.95 0.00 qt 196.6 F DISPLAY_STEP_TEMP 6.30 qt
TUN_TEMP 22.22222200
SPARGE_TEMP 75.55555600
PH 5.4
TUN_WEIGHT 1.81436800
TUN_SPECIFIC_HEAT 0.30000000
EQUIP_ADJUST FALSE
NOTES Simple single infusion mash for use with most modern well modified grains (about 95% of the time).
+DISPLAY_GRAIN_TEMP 72.0 F
+DISPLAY_TUN_TEMP 72.0
+DISPLAY_SPARGE_TEMP 168.0 F
+DISPLAY_TUN_WEIGHT 4.00 lb

MASH_STEPS (2)

MASH_STEP 1
*NAME Mash In
*VERSION 1
*TYPE Infusion
*INFUSE_AMOUNT 10.646532
*STEP_TEMP 67.77777800
*STEP_TIME 60
RAMP_TIME 2
END_TEMP 67.77777800
+DESCRIPTION Add 11.25 qt of water at 165.9 F
+WATER_GRAIN_RATIO 1.25
+DECOCTION_AMT 0.00 qt
+INFUSE_TEMP 165.9 F
+DISPLAY_STEP_TEMP DISPLAY_STEP_TEMP
+DISPLAY_INFUSE_AMT 11.25 qt
MASH_STEP 2
*NAME Mash Out
*VERSION 1
*TYPE Infusion
*INFUSE_AMOUNT 5.962058
*STEP_TEMP 75.55555600
*STEP_TIME 10
RAMP_TIME 2
END_TEMP 75.55555600
+DESCRIPTION Add 6.30 qt of water at 196.6 F
+WATER_GRAIN_RATIO 1.95
+DECOCTION_AMT 0.00 qt
+INFUSE_TEMP 196.6 F
+DISPLAY_STEP_TEMP DISPLAY_STEP_TEMP
+DISPLAY_INFUSE_AMT 6.30 qt
XSL file – “case-study-beer/beer.xsl”
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" exclude-result-prefixes="exslt">

    <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:include href="../../plugins/tenandtwo-xslt-processor/xsl/util.xsl"/>

    <!-- main -->
    <xsl:template match="/">

        <!-- get recipe number from $_REQUEST['recipe'] -->
        <xsl:variable name="recipe_idx">
            <xsl:call-template name="util-super-global">
                <xsl:with-param name="global" select="'_REQUEST'"/>
                <xsl:with-param name="index">recipe</xsl:with-param>
            </xsl:call-template>
        </xsl:variable>

        <!-- count recipes in the data -->
        <xsl:variable name="recipe_max">
            <xsl:value-of select="count(//RECIPE)"/>
        </xsl:variable>

        <!-- get final index of recipe to display -->
        <xsl:variable name="selected">
            <xsl:choose>
                <xsl:when test="$recipe_idx &gt; $recipe_max or $recipe_idx = 'last'">
                    <xsl:value-of select="$recipe_max"/>
                </xsl:when>
                <xsl:when test="$recipe_idx &gt; 0">
                    <xsl:value-of select="$recipe_idx"/>
                </xsl:when>
                <xsl:otherwise>1</xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <!-- begin output -->
        <xsl:apply-templates select="RECIPES">
            <xsl:with-param name="selected" select="number($selected)"/>
        </xsl:apply-templates>
    </xsl:template>


    <!-- RECIPES -->
    <xsl:template match="RECIPES">
        <xsl:param name="selected"/>

        <!-- output links -->
        <div id="beerxml-recipes">
            <h3>RECIPES</h3>
            <ol>
                <xsl:apply-templates select="RECIPE" mode="index">
                    <xsl:with-param name="selected" select="$selected"/>
                </xsl:apply-templates>
            </ol>
        </div>

        <!-- output details -->
        <xsl:apply-templates select="RECIPE[$selected]"/>

    </xsl:template>

    <!-- RECIPE -->
    <xsl:template match="RECIPE" mode="index">
        <xsl:param name="selected"/>

        <li>
        <xsl:choose>
            <xsl:when test="position() = $selected">
                <b>
                    <xsl:value-of disable-output-escaping="yes" select="NAME"/>
                </b>
            </xsl:when>
            <xsl:otherwise>
                <a>
                    <xsl:attribute name="href"><xsl:value-of select="concat('?recipe=',position())"/></xsl:attribute>
                    <xsl:value-of disable-output-escaping="yes" select="NAME"/>
                </a>
            </xsl:otherwise>
        </xsl:choose>
        </li>
    </xsl:template>

    <!-- RECIPE -->
    <xsl:template match="RECIPE">
        <div id="beerxml-recipe">
            <h2><xsl:value-of disable-output-escaping="yes" select="NAME"/></h2>
<!--
<xsl:call-template name="RECIPE_HEADER" />
<xsl:apply-templates select="STYLE" />
<xsl:apply-templates select="EQUIPMENT" />
<xsl:apply-templates select="HOPS" />
<xsl:apply-templates select="FERMENTABLES" />
<xsl:apply-templates select="MISCS" />
<xsl:apply-templates select="YEASTS" />
<xsl:apply-templates select="WATERS" />
<xsl:apply-templates select="MASH" />
<xsl:call-template name="RECIPE_FOOTER" />
 -->
            <div class="accordion" id="beerxml-recipe-sections">
                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-header">
                        <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-header" aria-expanded="true" aria-controls="section-body-header">
                            <h4>RECIPE-HEADER</h4>
                        </button>
                    </h2>
                    <div id="section-body-header" class="accordion-collapse collapse show" aria-labelledby="section-label-header">
                        <div class="accordion-body">
                            <xsl:call-template name="RECIPE_HEADER"/>
                        </div>
                    </div>
                </div>

                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-style">
                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-style" aria-expanded="false" aria-controls="section-body-style">
                            <h4>STYLE</h4>
                        </button>
                    </h2>
                    <div id="section-body-style" class="accordion-collapse collapse" aria-labelledby="section-label-style">
                        <div class="accordion-body">
                            <xsl:apply-templates select="STYLE"/>
                        </div>
                    </div>
                </div>

                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-equipment">
                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-equipment" aria-expanded="false" aria-controls="section-body-equipment">
                            <h4>EQUIPMENT</h4>
                        </button>
                    </h2>
                    <div id="section-body-equipment" class="accordion-collapse collapse" aria-labelledby="section-label-equipment">
                        <div class="accordion-body">
                            <xsl:apply-templates select="EQUIPMENT"/>
                        </div>
                    </div>
                </div>

                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-hops">
                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-hops" aria-expanded="false" aria-controls="section-body-hops">
                            <h4>HOPS (<xsl:value-of select="count(HOPS/HOP)"/>)</h4>
                        </button>
                    </h2>
                    <div id="section-body-hops" class="accordion-collapse collapse" aria-labelledby="section-label-hops">
                        <div class="accordion-body">
                            <xsl:apply-templates select="HOPS"/>
                        </div>
                    </div>
                </div>

                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-fermentables">
                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-fermentables" aria-expanded="false" aria-controls="section-body-fermentables">
                            <h4>FERMENTABLES (<xsl:value-of select="count(FERMENTABLES/FERMENTABLE)"/>)</h4>
                        </button>
                    </h2>
                    <div id="section-body-fermentables" class="accordion-collapse collapse" aria-labelledby="section-label-fermentables">
                        <div class="accordion-body">
                            <xsl:apply-templates select="FERMENTABLES"/>
                        </div>
                    </div>
                </div>

                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-miscs">
                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-miscs" aria-expanded="false" aria-controls="section-body-miscs">
                            <h4>MISCS (<xsl:value-of select="count(MISCS/MISC)"/>)</h4>
                        </button>
                    </h2>
                    <div id="section-body-miscs" class="accordion-collapse collapse" aria-labelledby="section-label-miscs">
                        <div class="accordion-body">
                            <xsl:apply-templates select="MISCS"/>
                        </div>
                    </div>
                </div>

                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-yeasts">
                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-yeasts" aria-expanded="false" aria-controls="section-body-yeasts">
                            <h4>YEASTS (<xsl:value-of select="count(YEASTS/YEAST)"/>)</h4>
                        </button>
                    </h2>
                    <div id="section-body-yeasts" class="accordion-collapse collapse" aria-labelledby="section-label-yeasts">
                        <div class="accordion-body">
                            <xsl:apply-templates select="YEASTS"/>
                        </div>
                    </div>
                </div>

                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-waters">
                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-waters" aria-expanded="false" aria-controls="section-body-waters">
                            <h4>WATERS (<xsl:value-of select="count(WATERS/WATER)"/>)</h4>
                        </button>
                    </h2>
                    <div id="section-body-waters" class="accordion-collapse collapse" aria-labelledby="section-label-waters">
                        <div class="accordion-body">
                            <xsl:apply-templates select="WATERS"/>
                        </div>
                    </div>
                </div>

                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-mash">
                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-mash" aria-expanded="false" aria-controls="section-body-mash">
                            <h4>MASH</h4>
                        </button>
                    </h2>
                    <div id="section-body-mash" class="accordion-collapse collapse" aria-labelledby="section-label-mash">
                        <div class="accordion-body">
                            <xsl:apply-templates select="MASH"/>
                        </div>
                    </div>
                </div>

                <div class="accordion-item">
                    <h2 class="accordion-header" id="section-label-footer">
                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#section-body-footer" aria-expanded="false" aria-controls="section-body-footer">
                            <h4>RECIPE_FOOTER</h4>
                        </button>
                    </h2>
                    <div id="section-body-footer" class="accordion-collapse collapse" aria-labelledby="section-label-footer">
                        <div class="accordion-body">
                            <xsl:call-template name="RECIPE_FOOTER"/>
                        </div>
                    </div>
                </div>
            </div>  <!-- end class="accordion" -->

        </div>  <!-- end id="beerxml-recipe" -->
    </xsl:template>

    <!-- -->
    <xsl:template name="RECIPE_HEADER">
        <div id="beerxml-recipe-header">
            <!-- <h4>RECIPE-HEADER</h4> -->
            <table class="table table-sm table-bordered">
            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*TYPE</td><td><xsl:value-of disable-output-escaping="yes" select="TYPE"/></td></tr>
            <tr><td class="text-end">*BREWER</td><td><xsl:value-of disable-output-escaping="yes" select="BREWER"/></td></tr>
            <xsl:if test="string-length(ASST_BREWER)">
                <tr><td class="text-end">ASST_BREWER</td><td><xsl:value-of disable-output-escaping="yes" select="ASST_BREWER"/></td></tr>
            </xsl:if>
            <tr><td class="text-end">*BATCH_SIZE</td><td><xsl:value-of disable-output-escaping="yes" select="BATCH_SIZE"/></td></tr>
            <tr><td class="text-end">*BOIL_SIZE</td><td><xsl:value-of disable-output-escaping="yes" select="BOIL_SIZE"/></td></tr>
            <tr><td class="text-end">*BOIL_TIME</td><td><xsl:value-of disable-output-escaping="yes" select="BOIL_TIME"/></td></tr>
            <tr><td class="text-end">*EFFICIENCY</td><td><xsl:value-of disable-output-escaping="yes" select="EFFICIENCY"/></td></tr>
            <xsl:if test="string-length(DATE)">
                <tr><td class="text-end">DATE</td><td><xsl:value-of disable-output-escaping="yes" select="DATE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(NOTES)">
                <tr><td class="text-end">NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="NOTES"/></td></tr>
            </xsl:if>
            </table>
        </div>
    </xsl:template>

    <!-- -->
    <xsl:template name="RECIPE_FOOTER">
        <div id="beerxml-recipe-footer">
            <!-- <h4>RECIPE_FOOTER</h4> -->
            <table class="table table-sm table-bordered">

            <xsl:if test="string-length(OG)">
                <tr><td class="text-end">OG</td><td><xsl:value-of disable-output-escaping="yes" select="OG"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(FG)">
                <tr><td class="text-end">FG</td><td><xsl:value-of disable-output-escaping="yes" select="FG"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(FERMENTATION_STAGES)">
                <tr><td class="text-end">FERMENTATION_STAGES</td><td><xsl:value-of disable-output-escaping="yes" select="FERMENTATION_STAGES"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(PRIMARY_AGE)">
                <tr><td class="text-end">PRIMARY_AGE</td><td><xsl:value-of disable-output-escaping="yes" select="PRIMARY_AGE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(PRIMARY_TEMP)">
                <tr><td class="text-end">PRIMARY_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="PRIMARY_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(SECONDARY_AGE)">
                <tr><td class="text-end">SECONDARY_AGE</td><td><xsl:value-of disable-output-escaping="yes" select="SECONDARY_AGE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(SECONDARY_TEMP)">
                <tr><td class="text-end">SECONDARY_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="SECONDARY_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TERTIARY_AGE)">
                <tr><td class="text-end">TERTIARY_AGE</td><td><xsl:value-of disable-output-escaping="yes" select="TERTIARY_AGE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TERTIARY_TEMP)">
                <tr><td class="text-end">TERTIARY_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="TERTIARY_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(AGE)">
                <tr><td class="text-end">AGE</td><td><xsl:value-of disable-output-escaping="yes" select="AGE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(AGE_TEMP)">
                <tr><td class="text-end">AGE_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="AGE_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(CARBONATION)">
                <tr><td class="text-end">CARBONATION</td><td><xsl:value-of disable-output-escaping="yes" select="CARBONATION"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(FORCED_CARBONATION)">
                <tr><td class="text-end">FORCED_CARBONATION</td><td><xsl:value-of disable-output-escaping="yes" select="FORCED_CARBONATION"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(PRIMING_SUGAR_NAME)">
                <tr><td class="text-end">PRIMING_SUGAR_NAME</td><td><xsl:value-of disable-output-escaping="yes" select="PRIMING_SUGAR_NAME"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(CARBONATION_TEMP)">
                <tr><td class="text-end">CARBONATION_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="CARBONATION_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(PRIMING_SUGAR_EQUIV)">
                <tr><td class="text-end">PRIMING_SUGAR_EQUIV</td><td><xsl:value-of disable-output-escaping="yes" select="PRIMING_SUGAR_EQUIV"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(KEG_PRIMING_FACTOR)">
                <tr><td class="text-end">KEG_PRIMING_FACTOR</td><td><xsl:value-of disable-output-escaping="yes" select="KEG_PRIMING_FACTOR"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TASTE_RATING)">
                <tr><td class="text-end">TASTE_RATING</td><td><xsl:value-of disable-output-escaping="yes" select="TASTE_RATING"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TASTE_NOTES)">
                <tr><td class="text-end">TASTE_NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="TASTE_NOTES"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(EST_OG)">
                <tr><td class="text-end">+EST_OG</td><td><xsl:value-of disable-output-escaping="yes" select="EST_OG"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(EST_FG)">
                <tr><td class="text-end">+EST_FG</td><td><xsl:value-of disable-output-escaping="yes" select="EST_FG"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(EST_COLOR)">
                <tr><td class="text-end">+EST_COLOR</td><td><xsl:value-of disable-output-escaping="yes" select="EST_COLOR"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(IBU)">
                <tr><td class="text-end">+IBU</td><td><xsl:value-of disable-output-escaping="yes" select="IBU"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(IBU_METHOD)">
                <tr><td class="text-end">+IBU_METHOD</td><td><xsl:value-of disable-output-escaping="yes" select="IBU_METHOD"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(EST_ABV)">
                <tr><td class="text-end">+EST_ABV</td><td><xsl:value-of disable-output-escaping="yes" select="EST_ABV"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ABV)">
                <tr><td class="text-end">+ABV</td><td><xsl:value-of disable-output-escaping="yes" select="ABV"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ACTUAL_EFFICIENCY)">
                <tr><td class="text-end">+ACTUAL_EFFICIENCY</td><td><xsl:value-of disable-output-escaping="yes" select="ACTUAL_EFFICIENCY"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(CALORIES)">
                <tr><td class="text-end">+CALORIES</td><td><xsl:value-of disable-output-escaping="yes" select="CALORIES"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_BATCH_SIZE)">
                <tr><td class="text-end">+DISPLAY_BATCH_SIZE</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_BATCH_SIZE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_BOIL_SIZE)">
                <tr><td class="text-end">+DISPLAY_BOIL_SIZE</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_BOIL_SIZE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_OG)">
                <tr><td class="text-end">+DISPLAY_OG</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_OG"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_FG)">
                <tr><td class="text-end">+DISPLAY_FG</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_FG"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_PRIMARY_TEMP)">
                <tr><td class="text-end">+DISPLAY_PRIMARY_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_PRIMARY_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_SECONDARY_TEMP)">
                <tr><td class="text-end">+DISPLAY_SECONDARY_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_SECONDARY_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TERTIARY_TEMP)">
                <tr><td class="text-end">+DISPLAY_TERTIARY_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TERTIARY_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_AGE_TEMP)">
                <tr><td class="text-end">+DISPLAY_AGE_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_AGE_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(CARBONATION_USED)">
                <tr><td class="text-end">+CARBONATION_USED</td><td><xsl:value-of disable-output-escaping="yes" select="CARBONATION_USED"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_CARB_TEMP)">
                <tr><td class="text-end">+DISPLAY_CARB_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_CARB_TEMP"/></td></tr>
            </xsl:if>

            </table>
        </div>
    </xsl:template>

    <!-- STYLE -->
    <xsl:template match="STYLE">
        <div id="beerxml-style">
            <!-- <h4>STYLE</h4> -->
            <table class="table table-sm table-bordered">

            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*CATEGORY</td><td><xsl:value-of disable-output-escaping="yes" select="CATEGORY"/></td></tr>
            <tr><td class="text-end">*CATEGORY_NUMBER</td><td><xsl:value-of disable-output-escaping="yes" select="CATEGORY_NUMBER"/></td></tr>
            <tr><td class="text-end">*STYLE_LETTER</td><td><xsl:value-of disable-output-escaping="yes" select="STYLE_LETTER"/></td></tr>
            <tr><td class="text-end">*STYLE_GUIDE</td><td><xsl:value-of disable-output-escaping="yes" select="STYLE_GUIDE"/></td></tr>
            <tr><td class="text-end">*TYPE</td><td><xsl:value-of disable-output-escaping="yes" select="TYPE"/></td></tr>
            <tr><td class="text-end">*OG_MIN</td><td><xsl:value-of disable-output-escaping="yes" select="OG_MIN"/></td></tr>
            <tr><td class="text-end">*OG_MAX</td><td><xsl:value-of disable-output-escaping="yes" select="OG_MAX"/></td></tr>
            <tr><td class="text-end">*FG_MIN</td><td><xsl:value-of disable-output-escaping="yes" select="FG_MIN"/></td></tr>
            <tr><td class="text-end">*FG_MAX</td><td><xsl:value-of disable-output-escaping="yes" select="FG_MAX"/></td></tr>
            <tr><td class="text-end">*IBU_MIN</td><td><xsl:value-of disable-output-escaping="yes" select="IBU_MIN"/></td></tr>
            <tr><td class="text-end">*IBU_MAX</td><td><xsl:value-of disable-output-escaping="yes" select="IBU_MAX"/></td></tr>
            <tr><td class="text-end">*COLOR_MIN</td><td><xsl:value-of disable-output-escaping="yes" select="COLOR_MIN"/></td></tr>
            <tr><td class="text-end">*COLOR_MAX</td><td><xsl:value-of disable-output-escaping="yes" select="COLOR_MAX"/></td></tr>

            <xsl:if test="string-length(CARB_MIN)">
                <tr><td class="text-end">CARB_MIN</td><td><xsl:value-of disable-output-escaping="yes" select="CARB_MIN"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(CARB_MAX)">
                <tr><td class="text-end">CARB_MAX</td><td><xsl:value-of disable-output-escaping="yes" select="CARB_MAX"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ABV_MIN)">
                <tr><td class="text-end">ABV_MIN</td><td><xsl:value-of disable-output-escaping="yes" select="ABV_MIN"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ABV_MAX)">
                <tr><td class="text-end">ABV_MAX</td><td><xsl:value-of disable-output-escaping="yes" select="ABV_MAX"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(PROFILE)">
                <tr><td class="text-end">PROFILE</td><td><xsl:value-of disable-output-escaping="yes" select="PROFILE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(INGREDIENTS)">
                <tr><td class="text-end">INGREDIENTS</td><td><xsl:value-of disable-output-escaping="yes" select="INGREDIENTS"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(EXAMPLES)">
                <tr><td class="text-end">EXAMPLES</td><td><xsl:value-of disable-output-escaping="yes" select="EXAMPLES"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(NOTES)">
                <tr><td class="text-end">NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="NOTES"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(DISPLAY_OG_MIN)">
                <tr><td class="text-end">+DISPLAY_OG_MIN</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_OG_MIN"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_OG_MAX)">
                <tr><td class="text-end">+DISPLAY_OG_MAX</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_OG_MAX"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_FG_MIN)">
                <tr><td class="text-end">+DISPLAY_FG_MIN</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_FG_MIN"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_FG_MAX)">
                <tr><td class="text-end">+DISPLAY_FG_MAX</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_FG_MAX"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_COLOR_MIN)">
                <tr><td class="text-end">+DISPLAY_COLOR_MIN</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_COLOR_MIN"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_COLOR_MAX)">
                <tr><td class="text-end">+DISPLAY_COLOR_MAX</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_COLOR_MAX"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(OG_RANGE)">
                <tr><td class="text-end">+OG_RANGE</td><td><xsl:value-of disable-output-escaping="yes" select="OG_RANGE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(FG_RANGE)">
                <tr><td class="text-end">+FG_RANGE</td><td><xsl:value-of disable-output-escaping="yes" select="FG_RANGE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(IBU_RANGE)">
                <tr><td class="text-end">+IBU_RANGE</td><td><xsl:value-of disable-output-escaping="yes" select="IBU_RANGE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(CARB_RANGE)">
                <tr><td class="text-end">+CARB_RANGE</td><td><xsl:value-of disable-output-escaping="yes" select="CARB_RANGE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(COLOR_RANGE)">
                <tr><td class="text-end">+COLOR_RANGE</td><td><xsl:value-of disable-output-escaping="yes" select="COLOR_RANGE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ABV_RANGE)">
                <tr><td class="text-end">+ABV_RANGE</td><td><xsl:value-of disable-output-escaping="yes" select="ABV_RANGE"/></td></tr>
            </xsl:if>

            </table>
        </div>
    </xsl:template>

    <!-- EQUIPMENT -->
    <xsl:template match="EQUIPMENT">
        <div id="beerxml-equipment">
            <!-- <h4>EQUIPMENT</h4> -->
            <table class="table table-sm table-bordered">

            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*BOIL_SIZE</td><td><xsl:value-of disable-output-escaping="yes" select="BOIL_SIZE"/></td></tr>
            <tr><td class="text-end">*BATCH_SIZE</td><td><xsl:value-of disable-output-escaping="yes" select="BATCH_SIZE"/></td></tr>

            <xsl:if test="string-length(TUN_VOLUME)">
                <tr><td class="text-end">TUN_VOLUME</td><td><xsl:value-of disable-output-escaping="yes" select="TUN_VOLUME"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TUN_WEIGHT)">
                <tr><td class="text-end">TUN_WEIGHT</td><td><xsl:value-of disable-output-escaping="yes" select="TUN_WEIGHT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TUN_SPECIFIC_HEAT)">
                <tr><td class="text-end">TUN_SPECIFIC_HEAT</td><td><xsl:value-of disable-output-escaping="yes" select="TUN_SPECIFIC_HEAT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TOP_UP_WATER)">
                <tr><td class="text-end">TOP_UP_WATER</td><td><xsl:value-of disable-output-escaping="yes" select="TOP_UP_WATER"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TRUB_CHILLER_LOSS)">
                <tr><td class="text-end">TRUB_CHILLER_LOSS</td><td><xsl:value-of disable-output-escaping="yes" select="TRUB_CHILLER_LOSS"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(EVAP_RATE)">
                <tr><td class="text-end">EVAP_RATE</td><td><xsl:value-of disable-output-escaping="yes" select="EVAP_RATE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(BOIL_TIME)">
                <tr><td class="text-end">BOIL_TIME</td><td><xsl:value-of disable-output-escaping="yes" select="BOIL_TIME"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(CALC_BOIL_VOLUME)">
                <tr><td class="text-end">CALC_BOIL_VOLUME</td><td><xsl:value-of disable-output-escaping="yes" select="CALC_BOIL_VOLUME"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(LAUTER_DEADSPACE)">
                <tr><td class="text-end">LAUTER_DEADSPACE</td><td><xsl:value-of disable-output-escaping="yes" select="LAUTER_DEADSPACE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TOP_UP_KETTLE)">
                <tr><td class="text-end">TOP_UP_KETTLE</td><td><xsl:value-of disable-output-escaping="yes" select="TOP_UP_KETTLE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(HOP_UTILIZATION)">
                <tr><td class="text-end">HOP_UTILIZATION</td><td><xsl:value-of disable-output-escaping="yes" select="HOP_UTILIZATION"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(NOTES)">
                <tr><td class="text-end">NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="NOTES"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(DISPLAY_BOIL_SIZE)">
                <tr><td class="text-end">+DISPLAY_BOIL_SIZE</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_BOIL_SIZE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_BATCH_SIZE)">
                <tr><td class="text-end">+DISPLAY_BATCH_SIZE</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_BATCH_SIZE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TUN_VOLUME)">
                <tr><td class="text-end">+DISPLAY_TUN_VOLUME</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TUN_VOLUME"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TUN_WEIGHT)">
                <tr><td class="text-end">+DISPLAY_TUN_WEIGHT</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TUN_WEIGHT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TOP_UP_WATER)">
                <tr><td class="text-end">+DISPLAY_TOP_UP_WATER</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TOP_UP_WATER"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TRUB_CHILLER_LOSS)">
                <tr><td class="text-end">+DISPLAY_TRUB_CHILLER_LOSS</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TRUB_CHILLER_LOSS"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_LAUTER_DEADSPACE)">
                <tr><td class="text-end">+DISPLAY_LAUTER_DEADSPACE</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_LAUTER_DEADSPACE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TOP_UP_KETTLE)">
                <tr><td class="text-end">+DISPLAY_TOP_UP_KETTLE</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TOP_UP_KETTLE"/></td></tr>
            </xsl:if>

            </table>
        </div>
    </xsl:template>

    <!-- HOPS -->
    <xsl:template match="HOPS">
        <div id="beerxml-hops">
            <!-- <h4>HOPS (<xsl:value-of select="count(HOP)" />)</h4> -->
            <xsl:apply-templates select="HOP"/>
        </div>
    </xsl:template>

    <!-- HOPS/HOP -->
    <xsl:template match="HOP">
        <div id="beerxml-hop">
            <h5>HOP <xsl:value-of select="position()"/></h5>
            <table class="table table-sm table-bordered">

            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*ALPHA</td><td><xsl:value-of disable-output-escaping="yes" select="ALPHA"/></td></tr>
            <tr><td class="text-end">*AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="AMOUNT"/></td></tr>
            <tr><td class="text-end">*USE</td><td><xsl:value-of disable-output-escaping="yes" select="USE"/></td></tr>
            <tr><td class="text-end">*TIME</td><td><xsl:value-of disable-output-escaping="yes" select="TIME"/></td></tr>

            <xsl:if test="string-length(TYPE)">
                <tr><td class="text-end">TYPE</td><td><xsl:value-of disable-output-escaping="yes" select="TYPE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(FORM)">
                <tr><td class="text-end">FORM</td><td><xsl:value-of disable-output-escaping="yes" select="FORM"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(BETA)">
                <tr><td class="text-end">BETA</td><td><xsl:value-of disable-output-escaping="yes" select="BETA"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(HSI)">
                <tr><td class="text-end">HSI</td><td><xsl:value-of disable-output-escaping="yes" select="HSI"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ORIGIN)">
                <tr><td class="text-end">ORIGIN</td><td><xsl:value-of disable-output-escaping="yes" select="ORIGIN"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(SUBSTITUTES)">
                <tr><td class="text-end">SUBSTITUTES</td><td><xsl:value-of disable-output-escaping="yes" select="SUBSTITUTES"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(HUMULENE)">
                <tr><td class="text-end">HUMULENE</td><td><xsl:value-of disable-output-escaping="yes" select="HUMULENE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(CARYOPHYLLENE)">
                <tr><td class="text-end">CARYOPHYLLENE</td><td><xsl:value-of disable-output-escaping="yes" select="CARYOPHYLLENE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(COHUMULONE)">
                <tr><td class="text-end">COHUMULONE</td><td><xsl:value-of disable-output-escaping="yes" select="COHUMULONE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(MYRCENE)">
                <tr><td class="text-end">MYRCENE</td><td><xsl:value-of disable-output-escaping="yes" select="MYRCENE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(NOTES)">
                <tr><td class="text-end">NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="NOTES"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(DISPLAY_AMOUNT)">
                <tr><td class="text-end">+DISPLAY_AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_AMOUNT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(INVENTORY)">
                <tr><td class="text-end">+INVENTORY</td><td><xsl:value-of disable-output-escaping="yes" select="INVENTORY"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TIME)">
                <tr><td class="text-end">+DISPLAY_TIME</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TIME"/></td></tr>
            </xsl:if>

            </table>
        </div>
    </xsl:template>

    <!-- FERMENTABLES -->
    <xsl:template match="FERMENTABLES">
        <div id="beerxml-fermentables">
            <!-- <h4>FERMENTABLES (<xsl:value-of select="count(FERMENTABLE)" />)</h4> -->
            <xsl:apply-templates select="FERMENTABLE"/>
        </div>
    </xsl:template>

    <!-- FERMENTABLES/FERMENTABLE -->
    <xsl:template match="FERMENTABLE">
        <div id="beerxml-fermentable">
            <h5>FERMENTABLE <xsl:value-of select="position()"/></h5>
            <table class="table table-sm table-bordered">

            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*TYPE</td><td><xsl:value-of disable-output-escaping="yes" select="TYPE"/></td></tr>
            <tr><td class="text-end">*AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="AMOUNT"/></td></tr>
            <tr><td class="text-end">*YIELD</td><td><xsl:value-of disable-output-escaping="yes" select="YIELD"/></td></tr>

            <xsl:if test="string-length(COLOR)">
                <tr><td class="text-end">COLOR</td><td><xsl:value-of disable-output-escaping="yes" select="COLOR"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ADD_AFTER_BOIL)">
                <tr><td class="text-end">ADD_AFTER_BOIL</td><td><xsl:value-of disable-output-escaping="yes" select="ADD_AFTER_BOIL"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ORIGIN)">
                <tr><td class="text-end">ORIGIN</td><td><xsl:value-of disable-output-escaping="yes" select="ORIGIN"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(SUPPLIER)">
                <tr><td class="text-end">SUPPLIER</td><td><xsl:value-of disable-output-escaping="yes" select="SUPPLIER"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(COARSE_FINE_DIFF)">
                <tr><td class="text-end">COARSE_FINE_DIFF</td><td><xsl:value-of disable-output-escaping="yes" select="COARSE_FINE_DIFF"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(MOISTURE)">
                <tr><td class="text-end">MOISTURE</td><td><xsl:value-of disable-output-escaping="yes" select="MOISTURE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DIASTATIC_POWER)">
                <tr><td class="text-end">DIASTATIC_POWER</td><td><xsl:value-of disable-output-escaping="yes" select="DIASTATIC_POWER"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(PROTEIN)">
                <tr><td class="text-end">PROTEIN</td><td><xsl:value-of disable-output-escaping="yes" select="PROTEIN"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(MAX_IN_BATCH)">
                <tr><td class="text-end">MAX_IN_BATCH</td><td><xsl:value-of disable-output-escaping="yes" select="MAX_IN_BATCH"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(RECOMMEND_MASH)">
                <tr><td class="text-end">RECOMMEND_MASH</td><td><xsl:value-of disable-output-escaping="yes" select="RECOMMEND_MASH"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(IBU_GAL_PER_LB)">
                <tr><td class="text-end">IBU_GAL_PER_LB</td><td><xsl:value-of disable-output-escaping="yes" select="IBU_GAL_PER_LB"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(NOTES)">
                <tr><td class="text-end">NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="NOTES"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(DISPLAY_AMOUNT)">
                <tr><td class="text-end">+DISPLAY_AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_AMOUNT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(POTENTIAL)">
                <tr><td class="text-end">+POTENTIAL</td><td><xsl:value-of disable-output-escaping="yes" select="POTENTIAL"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(INVENTORY)">
                <tr><td class="text-end">+INVENTORY</td><td><xsl:value-of disable-output-escaping="yes" select="INVENTORY"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_COLOR)">
                <tr><td class="text-end">+DISPLAY_COLOR</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_COLOR"/></td></tr>
            </xsl:if>

            </table>
        </div>
    </xsl:template>

    <!-- MISCS -->
    <xsl:template match="MISCS">
        <div id="beerxml-miscs">
            <!-- <h4>MISCS (<xsl:value-of select="count(MISC)" />)</h4> -->
            <xsl:apply-templates select="MISC"/>
        </div>
    </xsl:template>

    <!-- MISCS/MISC-->
    <xsl:template match="MISC">
        <div id="beerxml-misc">
            <h5>MISC <xsl:value-of select="position()"/></h5>
            <table class="table table-sm table-bordered">

            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*TYPE</td><td><xsl:value-of disable-output-escaping="yes" select="TYPE"/></td></tr>
            <tr><td class="text-end">*USE</td><td><xsl:value-of disable-output-escaping="yes" select="USE"/></td></tr>
            <tr><td class="text-end">*TIME</td><td><xsl:value-of disable-output-escaping="yes" select="TIME"/></td></tr>
            <tr><td class="text-end">*AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="AMOUNT"/></td></tr>

            <xsl:if test="string-length(AMOUNT_IS_WEIGHT)">
                <tr><td class="text-end">AMOUNT_IS_WEIGHT</td><td><xsl:value-of disable-output-escaping="yes" select="AMOUNT_IS_WEIGHT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(USE_FOR)">
                <tr><td class="text-end">USE_FOR</td><td><xsl:value-of disable-output-escaping="yes" select="USE_FOR"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(NOTES)">
                <tr><td class="text-end">NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="NOTES"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(DISPLAY_AMOUNT)">
                <tr><td class="text-end">+DISPLAY_AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_AMOUNT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(INVENTORY)">
                <tr><td class="text-end">+INVENTORY</td><td><xsl:value-of disable-output-escaping="yes" select="INVENTORY"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TIME)">
                <tr><td class="text-end">+DISPLAY_TIME</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TIME"/></td></tr>
            </xsl:if>

            </table>
        </div>
    </xsl:template>

    <!-- YEASTS -->
    <xsl:template match="YEASTS">
        <div id="beerxml-yeasts">
            <!-- <h4>YEASTS (<xsl:value-of select="count(YEAST)" />)</h4> -->
            <xsl:apply-templates select="YEAST"/>
        </div>
    </xsl:template>

    <!-- YEASTS/YEAST -->
    <xsl:template match="YEAST">
        <div id="beerxml-yeast">
            <h5>YEAST <xsl:value-of select="position()"/></h5>
            <table class="table table-sm table-bordered">

            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*TYPE</td><td><xsl:value-of disable-output-escaping="yes" select="TYPE"/></td></tr>
            <tr><td class="text-end">*FORM</td><td><xsl:value-of disable-output-escaping="yes" select="FORM"/></td></tr>
            <tr><td class="text-end">*AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="AMOUNT"/></td></tr>

            <xsl:if test="string-length(AMOUNT_IS_WEIGHT)">
                <tr><td class="text-end">AMOUNT_IS_WEIGHT</td><td><xsl:value-of disable-output-escaping="yes" select="AMOUNT_IS_WEIGHT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(LABORATORY)">
                <tr><td class="text-end">LABORATORY</td><td><xsl:value-of disable-output-escaping="yes" select="LABORATORY"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(PRODUCT_ID)">
                <tr><td class="text-end">PRODUCT_ID</td><td><xsl:value-of disable-output-escaping="yes" select="PRODUCT_ID"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(MIN_TEMPERATURE)">
                <tr><td class="text-end">MIN_TEMPERATURE</td><td><xsl:value-of disable-output-escaping="yes" select="MIN_TEMPERATURE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(MAX_TEMPERATURE)">
                <tr><td class="text-end">MAX_TEMPERATURE</td><td><xsl:value-of disable-output-escaping="yes" select="MAX_TEMPERATURE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(FLOCCULATION)">
                <tr><td class="text-end">FLOCCULATION</td><td><xsl:value-of disable-output-escaping="yes" select="FLOCCULATION"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ATTENUATION)">
                <tr><td class="text-end">ATTENUATION</td><td><xsl:value-of disable-output-escaping="yes" select="ATTENUATION"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(BEST_FOR)">
                <tr><td class="text-end">BEST_FOR</td><td><xsl:value-of disable-output-escaping="yes" select="BEST_FOR"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TIMES_CULTURED)">
                <tr><td class="text-end">TIMES_CULTURED</td><td><xsl:value-of disable-output-escaping="yes" select="TIMES_CULTURED"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(MAX_REUSE)">
                <tr><td class="text-end">MAX_REUSE</td><td><xsl:value-of disable-output-escaping="yes" select="MAX_REUSE"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(ADD_TO_SECONDARY)">
                <tr><td class="text-end">ADD_TO_SECONDARY</td><td><xsl:value-of disable-output-escaping="yes" select="ADD_TO_SECONDARY"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(NOTES)">
                <tr><td class="text-end">NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="NOTES"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(DISPLAY_AMOUNT)">
                <tr><td class="text-end">+DISPLAY_AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_AMOUNT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISP_MIN_TEMP)">
                <tr><td class="text-end">+DISP_MIN_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISP_MIN_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISP_MAX_TEMP)">
                <tr><td class="text-end">+DISP_MAX_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISP_MAX_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(INVENTORY)">
                <tr><td class="text-end">+INVENTORY</td><td><xsl:value-of disable-output-escaping="yes" select="INVENTORY"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(CULTURE_DATE)">
                <tr><td class="text-end">+CULTURE_DATE</td><td><xsl:value-of disable-output-escaping="yes" select="CULTURE_DATE"/></td></tr>
            </xsl:if>

            </table>
        </div>
    </xsl:template>

    <!-- WATERS -->
    <xsl:template match="WATERS">
        <div id="beerxml-waters">
            <!-- <h4>WATERS (<xsl:value-of select="count(WATER)" />)</h4> -->
            <xsl:apply-templates select="WATER"/>
        </div>
    </xsl:template>

    <!-- WATERS/WATER -->
    <xsl:template match="WATER">
        <div id="beerxml-water">
            <h5>WATER <xsl:value-of select="position()"/></h5>
            <table class="table table-sm table-bordered">

            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="AMOUNT"/></td></tr>
            <tr><td class="text-end">*CALCIUM</td><td><xsl:value-of disable-output-escaping="yes" select="CALCIUM"/></td></tr>
            <tr><td class="text-end">*BICARBONATE</td><td><xsl:value-of disable-output-escaping="yes" select="BICARBONATE"/></td></tr>
            <tr><td class="text-end">*SULFATE</td><td><xsl:value-of disable-output-escaping="yes" select="SULFATE"/></td></tr>
            <tr><td class="text-end">*CHLORIDE</td><td><xsl:value-of disable-output-escaping="yes" select="CHLORIDE"/></td></tr>
            <tr><td class="text-end">*SODIUM</td><td><xsl:value-of disable-output-escaping="yes" select="SODIUM"/></td></tr>
            <tr><td class="text-end">*MAGNESIUM</td><td><xsl:value-of disable-output-escaping="yes" select="MAGNESIUM"/></td></tr>

            <xsl:if test="string-length(PH)">
                <tr><td class="text-end">PH</td><td><xsl:value-of disable-output-escaping="yes" select="PH"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(NOTES)">
                <tr><td class="text-end">NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="NOTES"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(DISPLAY_AMOUNT)">
                <tr><td class="text-end">+DISPLAY_AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_AMOUNT"/></td></tr>
            </xsl:if>

            </table>
        </div>
    </xsl:template>

    <!-- MASH -->
    <xsl:template match="MASH">
        <div id="beerxml-mash">
            <!-- <h4>MASH</h4> -->
            <table class="table table-sm table-bordered">

            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*GRAIN_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="GRAIN_TEMP"/></td></tr>
            <tr><td class="text-end">*MASH_STEPS</td><td><xsl:value-of disable-output-escaping="yes" select="MASH_STEPS"/></td></tr>

            <xsl:if test="string-length(TUN_TEMP)">
                <tr><td class="text-end">TUN_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="TUN_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(SPARGE_TEMP)">
                <tr><td class="text-end">SPARGE_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="SPARGE_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(PH)">
                <tr><td class="text-end">PH</td><td><xsl:value-of disable-output-escaping="yes" select="PH"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TUN_WEIGHT)">
                <tr><td class="text-end">TUN_WEIGHT</td><td><xsl:value-of disable-output-escaping="yes" select="TUN_WEIGHT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(TUN_SPECIFIC_HEAT)">
                <tr><td class="text-end">TUN_SPECIFIC_HEAT</td><td><xsl:value-of disable-output-escaping="yes" select="TUN_SPECIFIC_HEAT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(EQUIP_ADJUST)">
                <tr><td class="text-end">EQUIP_ADJUST</td><td><xsl:value-of disable-output-escaping="yes" select="EQUIP_ADJUST"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(NOTES)">
                <tr><td class="text-end">NOTES</td><td><xsl:value-of disable-output-escaping="yes" select="NOTES"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(DISPLAY_GRAIN_TEMP)">
                <tr><td class="text-end">+DISPLAY_GRAIN_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_GRAIN_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TUN_TEMP)">
                <tr><td class="text-end">+DISPLAY_TUN_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TUN_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_SPARGE_TEMP)">
                <tr><td class="text-end">+DISPLAY_SPARGE_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_SPARGE_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_TUN_WEIGHT)">
                <tr><td class="text-end">+DISPLAY_TUN_WEIGHT</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_TUN_WEIGHT"/></td></tr>
            </xsl:if>

            </table>
            <xsl:apply-templates select="MASH_STEPS"/>
        </div>
    </xsl:template>

    <!-- MASH/MASH_STEPS -->
    <xsl:template match="MASH_STEPS">
        <div id="beerxml-mash-steps">
            <h4>MASH_STEPS (<xsl:value-of select="count(MASH_STEP)"/>)</h4>
            <xsl:apply-templates select="MASH_STEP"/>
        </div>
    </xsl:template>

    <!-- MASH/MASH_STEPS/MASH_STEP -->
    <xsl:template match="MASH_STEP">
        <div id="beerxml-mash-step">
            <h5>MASH_STEP <xsl:value-of select="position()"/></h5>
            <table class="table table-sm table-bordered">

            <tr><td class="text-end">*NAME</td><td><xsl:value-of disable-output-escaping="yes" select="NAME"/></td></tr>
            <tr><td class="text-end">*VERSION</td><td><xsl:value-of disable-output-escaping="yes" select="VERSION"/></td></tr>
            <tr><td class="text-end">*TYPE</td><td><xsl:value-of disable-output-escaping="yes" select="TYPE"/></td></tr>
            <tr><td class="text-end">*INFUSE_AMOUNT</td><td><xsl:value-of disable-output-escaping="yes" select="INFUSE_AMOUNT"/></td></tr>
            <tr><td class="text-end">*STEP_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="STEP_TEMP"/></td></tr>
            <tr><td class="text-end">*STEP_TIME</td><td><xsl:value-of disable-output-escaping="yes" select="STEP_TIME"/></td></tr>

            <xsl:if test="string-length(RAMP_TIME)">
                <tr><td class="text-end">RAMP_TIME</td><td><xsl:value-of disable-output-escaping="yes" select="RAMP_TIME"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(END_TEMP)">
                <tr><td class="text-end">END_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="END_TEMP"/></td></tr>
            </xsl:if>

            <xsl:if test="string-length(DESCRIPTION)">
                <tr><td class="text-end">+DESCRIPTION</td><td><xsl:value-of disable-output-escaping="yes" select="DESCRIPTION"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(WATER_GRAIN_RATIO)">
                <tr><td class="text-end">+WATER_GRAIN_RATIO</td><td><xsl:value-of disable-output-escaping="yes" select="WATER_GRAIN_RATIO"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DECOCTION_AMT)">
                <tr><td class="text-end">+DECOCTION_AMT</td><td><xsl:value-of disable-output-escaping="yes" select="DECOCTION_AMT"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(INFUSE_TEMP)">
                <tr><td class="text-end">+INFUSE_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="INFUSE_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_STEP_TEMP)">
                <tr><td class="text-end">+DISPLAY_STEP_TEMP</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_STEP_TEMP"/></td></tr>
            </xsl:if>
            <xsl:if test="string-length(DISPLAY_INFUSE_AMT)">
                <tr><td class="text-end">+DISPLAY_INFUSE_AMT</td><td><xsl:value-of disable-output-escaping="yes" select="DISPLAY_INFUSE_AMT"/></td></tr>
            </xsl:if>

            </table>
        </div>
    </xsl:template>

</xsl:stylesheet><!-- end beer.xsl -->