StrugglingToCode
StrugglingToCode

Reputation: 3

XSL Choosing the correct substring based on conditions

I am transitioning from a simple 2 substring with a ' ' delimiter that currently uses the substring-before and substring-after, but now I am needing to modify it to accommodate multiple substrings that vary in quantity. I have tried several different methods I have found on this side but I am either too much of a rookie to even understand it or I don't think it would work.

<xsl:template name="print_cmp_code_by_color_and_subtype"><xsl:param name="code"/><xsl:param name="color_code"/><xsl:param name="subtype_code"/>
        <xsl:choose>
            <xsl:when test="contains($code,' ')">
                <xsl:call-template name="print_cmp_code_by_color_and_subtype">
                    <xsl:with-param name="code" select="normalize-space(substring-before($code,' '))"/>
                    <xsl:with-param name="color_code" select="$color_code"/>
                    <xsl:with-param name="subtype_code" select="$subtype_code"/>
                </xsl:call-template>
                <xsl:call-template name="print_cmp_code_by_color_and_subtype">
                    <xsl:with-param name="code" select="normalize-space(substring-after($code,' '))"/>
                    <xsl:with-param name="color_code" select="$color_code"/>
                    <xsl:with-param name="subtype_code" select="$subtype_code"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:if test="contains($code,'=')">
                    <xsl:if test="normalize-space(substring-before($code,'='))=$color_code">
                        <xsl:value-of select="normalize-space(substring-after($code,'='))"/>
                    </xsl:if>
                </xsl:if>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
<itemNo>
                    <xsl:choose>
                        <xsl:when test="cmp_code">
                            <xsl:choose>
                                <xsl:when test="contains(cmp_code,'=')">
                                    <xsl:call-template name="print_cmp_code_by_color">
                                        <xsl:with-param name="code" select="cmp_code"/>
                                        <xsl:with-param name="color_code" select="colors/color[col_type='external']/col_code"/>
                                        <xsl:with-param name="subtype_code" select="cmp_options/coption/opt_values/opt_value[(ov_keywords_list/keyword='SAGE') and (ov_active='true')]/ov_description"/>
                                    </xsl:call-template>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="cmp_code"/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="cmp_series_code"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </itemNo>

The input for the code parameter is the issue. I went from "Dog=9500 Cat=9502" to "Dog_BX=9500 Dog_CX=9502 Cat_BX=9856-BX Cat_CX=9856-CX Elephant=9787 Cow=8734

Sometimes it has a subtype, sometimes it doesn't. Sometimes it needs the color code, sometimes not.

The animal name is the subtype_code, and the BX or CX is the color_code.

The value I am trying to pass through is the corresponding substring where if the string contains an "=", then uses the substring with the matching color_code in the XML. If the substrings contain a "_", it uses the substring that matches the XMLs subtype_code. If it has "=" and "_" then it use the substring that matches the XMLs color_code and subtype_code.

I am so lost and in need of help.

Edit 1: If the color_code in the XML was "CX" and the subtype code in the XML was "Cat" then the expected output would be "9856-CX". the desired output eventually is a json

"itemNo": "9856-CX",
"qty": "1",
"jobNo": "230108",
"batchNo": "-01",
"materials": [
{
"itemNo": "6285-BX",
"qty": "6.677",
"UOM": "FEET",
"location": "230108"
}

the example of the json above is incomplete, however my main focus is parsing the correct parent itemNo to send to SAGE300

XSLT 1.0

<?xml version="1.0" encoding="UTF-8"?>
<jobs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xfatcom2.xsd" generated="2024-04-04T16:14:13" version="2.0">
<job>
<PKEY>1</PKEY>
<ID>19444</ID>
<job_id>162</job_id>
<job_year>2024</job_year>
<job_name>9999999999</job_name>
<job_components>
<component>
<PKEY>26</PKEY>
<FKEY>1</FKEY>
<cmp_code>Dog_BX=9500 Dog_CX=9502 Cat_BX=9856-BX Cat_CX=9856-CX Elephant=9787 Cow=8734</cmp_code>
<colors>
<color>
<PKEY>38</PKEY>
<FKEY>36</FKEY>
<col_type>external</col_type>
<col_code>BX</col_code>
</color>
</colors>
<cmp_options>
<coption>
<opt_values>
<opt_value>
<ov_description>Cat</ov_description>
<ov_keywords_list>
<keyword>SAGE</keyword>
</ov_keywords_list>
<ov_active>true</ov_active>
</opt_value>
</opt_values>
</coption>
</cmp_options>
</component>
<component>
<PKEY>26</PKEY>
<FKEY>1</FKEY>
<cmp_code>Dog_BX=9500 Dog_CX=9502 Cat_BX=9856-BX Cat_CX=9856-CX Elephant=9787 Cow=8734</cmp_code>
<colors>
<color>
<PKEY>38</PKEY>
<FKEY>36</FKEY>
<col_type>external</col_type>
<col_code>CX</col_code>
</color>
</colors>
<cmp_options>
<coption>
<opt_values>
<opt_value>
<ov_description>Dog</ov_description>
<ov_keywords_list>
<keyword>SAGE</keyword>
</ov_keywords_list>
<ov_active>true</ov_active>
</opt_value>
</opt_values>
</coption>
</cmp_options>
</component>
<component>
<PKEY>26</PKEY>
<FKEY>1</FKEY>
<cmp_code>Dog_BX=9500 Dog_CX=9502 Cat_BX=9856-BX Cat_CX=9856-CX Elephant=9787 Cow=8734</cmp_code>
<colors>
<color>
<PKEY>38</PKEY>
<FKEY>36</FKEY>
<col_type>external</col_type>
<col_code>CX</col_code>
</color>
</colors>
<cmp_options>
<coption>
<opt_values>
<opt_value>
<ov_description>Elephant</ov_description>
<ov_keywords_list>
<keyword>SAGE</keyword>
</ov_keywords_list>
<ov_active>true</ov_active>
</opt_value>
</opt_values>
</coption>
</cmp_options>
</component>
</job_components>
</job>
</jobs>

Upvotes: 0

Views: 96

Answers (2)

StrugglingToCode
StrugglingToCode

Reputation: 3

<xsl:template name="split">
        <xsl:param name="code"/>
        <xsl:param name="color_code" select="concat(cmp_options/coption/opt_values/opt_value[(ov_keywords_list/keyword='SAGE') and (ov_active='true')]/opt_code, colors/color[col_type='external']/col_code)"/>
            <xsl:choose>
                <xsl:when test="contains($code, $color_code)">
                    <xsl:call-template name="split">
                        <xsl:with-param name="code" select="substring-after($code, $color_code)"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="substring-before(substring-after(concat($code,' '),'='),' ')"/>
            </xsl:otherwise>
        </xsl:choose>
</xsl:template>

So I ended up spending about 2 days just looking for the right method, and found Henrik Hanson's "split string and loop" on GitHub. I still have no idea what I'm doing, but I was able to trial and error different combinations of various things.

Upvotes: 0

michael.hor257k
michael.hor257k

Reputation: 117043

Your question is still not clear, but maybe you could use this as your starting point:

XML

<input>
    <item subtype_code="Cat" color_code="CX"/>
    <item subtype_code="Elephant"/>
</input>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:param name="code">Dog_BX=9500 Dog_CX=9502 Cat_BX=9856-BX Cat_CX=9856-CX Elephant=9787 Cow=8734</xsl:param>

<xsl:template match="/input">
    <output>
        <xsl:for-each select="item">
            <item subtype_code="{@subtype_code}" color_code="{@color_code}">
                <xsl:variable name="key">
                    <xsl:value-of select="@subtype_code"/>
                    <xsl:if test="@color_code">
                        <xsl:value-of select="concat('_', @color_code)"/>
                    </xsl:if>
                    <xsl:text>=</xsl:text>
                </xsl:variable>
                <xsl:value-of select="substring-before(substring-after(concat($code, ' '), $key), ' ')"/>
            </item>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>

Result

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <item subtype_code="Cat" color_code="CX">9856-CX</item>
   <item subtype_code="Elephant" color_code="">9787</item>
</output>

Upvotes: 0

Related Questions