Delimited strings matching pattern

2019-09-12 09:17发布

问题:

Being relatively inexperienced in XSLT, I am facing a problem and need some help from XSLT expert.

The following product types and its related codes are 1 to 1 matching in different delimited strings. I need to extract two at a time from the same position of two strings (see example below). Also, the number of product types and product codes in the delimited strings can vary.

<OFFERINGS>

  <PRODUCT>
    <attribute name="PRODUCT_TYPES" value="GUL5, RIDER, LIR, WAIVER" />
    <attribute name="PRODUCT_CODES" value="SLG3AA, R001,  LIR3, PW0001" />
  </PRODUCT>

  <PRODUCT>
    <attribute name="PRODUCT_TYPES" value="TERM8, WAIVER2" />
    <attribute name="PRODUCT_CODES" value="SP0007, PW0002" />
  </PRODUCT>

</OFFERINGS>

To

<COVERAGES>

  <GROUP_COVERAGE>
    <COVERAGE>
        <PRODUCT_TYPE>GUL5</PRODUCT_TYPE>
        <PRODUCT_CODE>SLG3AA</PRODUCT_CODE>
    </COVERAGE>
    <COVERAGE>
        <PRODUCT_TYPE>RIDER</PRODUCT_TYPE>
        <PRODUCT_CODE>R001</PRODUCT_CODE>
    </COVERAGE>
    <COVERAGE>
        <PRODUCT_TYPE>LIR</PRODUCT_TYPE>
        <PRODUCT_CODE>LIR3</PRODUCT_CODE>
    </COVERAGE>
    <COVERAGE>
        <PRODUCT_TYPE>WAIVER</PRODUCT_TYPE>
        <PRODUCT_CODE>PW0001</PRODUCT_CODE>
    </COVERAGE>
  </GROUP_COVERAGE>

  <GROUP_COVERAGE>
    <COVERAGE>
        <PRODUCT_TYPE>TERM8</PRODUCT_TYPE>
        <PRODUCT_CODE>SP0007</PRODUCT_CODE>
    </COVERAGE>
    <COVERAGE>
        <PRODUCT_TYPE>WAIVER2</PRODUCT_TYPE>
        <PRODUCT_CODE>PW0002</PRODUCT_CODE>
    </COVERAGE>
  </GROUP_COVERAGE>
</COVERAGES>

回答1:

All you have to do is take the tokenizing template from your previous question and adapt it to use two text parameters instead of one:

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:strip-space elements="*"/>

<xsl:template match="/OFFERINGS">
    <COVERAGES>
        <xsl:apply-templates/>
    </COVERAGES>
</xsl:template>

<xsl:template match="PRODUCT">
    <COVERAGE>
        <xsl:call-template name="tokenize">
            <xsl:with-param name="types" select="attribute[@name='PRODUCT_TYPES']/@value"/>
            <xsl:with-param name="codes" select="attribute[@name='PRODUCT_CODES']/@value"/>
        </xsl:call-template>
    </COVERAGE>
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="types"/>
    <xsl:param name="codes"/>
    <xsl:param name="delimiter" select="', '"/>
    <xsl:variable name="type" select="substring-before(concat($types, $delimiter), $delimiter)" />
    <xsl:variable name="code" select="substring-before(concat($codes, $delimiter), $delimiter)" />
        <xsl:if test="$type">
            <COVERAGE>
                <PRODUCT_TYPE>
                    <xsl:value-of select="$type"/>
                </PRODUCT_TYPE>
                <PRODUCT_CODE>
                    <xsl:value-of select="$code"/>
                </PRODUCT_CODE>
            </COVERAGE>
        </xsl:if>
        <xsl:if test="contains($types, $delimiter)">
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="types" select="substring-after($types, $delimiter)"/>
                <xsl:with-param name="codes" select="substring-after($codes, $delimiter)"/>
            </xsl:call-template>
        </xsl:if>
</xsl:template>

</xsl:stylesheet>


标签: xml xslt