XSLT recursive get main category name list instance

Source: Internet
Author: User
Tags documentation xsl xslt

This article is about sharing a small example of XSLT and XML at work

Requirements: XML throws some classes of primary and sub classifications, in which the neutron classification of different main classifications is repeated, and each main classification and subcategory are output in the form of a recordset. It is now required to filter out the main classification.

1. XML data:

The code is as follows Copy Code

< XML version= "1.0" encoding= "UTF-8"?>
<rows>
<row>
<area>Carrier</area>
<complainttype>Damage</complainttype>
</row>
<row>
<area>Carrier</area>
<complainttype>delivery problem</complainttype>
</row>
<row>
<area>Carrier</area>
<complainttype>Documentation</complainttype>
</row>
<row>
<area>Carrier</area>
<complainttype>Excess</complainttype>
</row>
<row>
<area>consumer &amp; Office</area>
<complainttype>Brochures/catalogs</complainttype>
</row>
<row>
<area>consumer &amp; Office</area>
<complainttype>Commission/rebate</complainttype>
</row>
<row>
<area>Customer</area>
<complainttype>Commission/rebate</complainttype>
</row>
<row>
<area>Customer</area>
<complainttype>Credit/Overdues</complainttype>
</row>
<row>
<area>Customer</area>
<complainttype>delivery problem</complainttype>
</row>
<row>
<area>Customer</area>
<complainttype>Documentation</complainttype>
</row>
<row>
<area>Customer</area>
<complainttype>duty exemption</complainttype>
</row>
<row>
<area>Customer</area>
<complainttype>Excess</complainttype>
</row>
<row>
<area>Customer</area>
<complainttype>Imco</complainttype>
</row>
<row>
<area>Customer</area>
<complainttype>order routing</complainttype>
</row>
<row>
<area>DC</area>
<complainttype>Excess</complainttype>
</row>
</rows>

2. XSLT code:

The code is as follows Copy Code
< XML version= "1.0" encoding= "UTF-8"?>
<xsl:stylesheet xmlns:xsl= "Http://www.w3.org/1999/XSL/Transform" version= "1.0" >
<xsl:output method= "html" version= "1.0" omit-xml-declaration= "yes"/>

<xsl:template match= "/" >
<xsl:variable name= "Optionsstr" >
<xsl:for-each select= "Descendant::row/area" ><xsl:value-of select= "." />###</xsl:for>
</xsl:variable>
<!--optionstr output:
carrier## #Carrier # # #Carrier # # #Carrier # # #Consumer &amp; office## #Consumer &amp; office## #Customer # # #Customer # # #Customer # #Customer # # #Customer # #Customer # # # # #Customer # # #Customer # #
-->

<p>
<select name= "Area" >
<option value= "" >--Select--</option>
<xsl:call-template name= "Areaoptions" >
<xsl:with-param name= "Optionsstr" select= "$optionsStr"/>
</xsl:call>
</select>
</p>
</xsl:template>

<!--remove Repeat area-->
<xsl:template name= "Areaoptions" >
<xsl:param name= "Optionsstr"/>
<!--normalize-space () for remove n-->

<!--option: The first option to intercept-->
<xsl:variable name= "option" ><xsl:value-of select= "Normalize-space (Substring-before ($optionsStr, ' ### ')" /></xsl:variable>
<!--newstr: The remaining string after intercepting the first option-->
<xsl:variable name= "Newstr" ><xsl:value-of select= "Normalize-space (Substring-after ($optionsStr, ' ### ')") " ></xsl:variable>
<!--newoption: The second option to intercept-->
<xsl:variable name= "newoption" ><xsl:value-of select= "Normalize-space (Substring-before ($newStr, ' ### ')") " ></xsl:variable>

<!--only if the first option that is intercepted is different from the second option, the option does not repeat-->
<xsl:if test= "$newOption!= $option" >
<option>
<xsl:attribute name= "value" ><xsl:value-of select= "/descendant::row[area = $option]/area"/></xsl: Attribute>
<xsl:value-of select= "$option"/>
</option>
</xsl:if>

<!--if both OPTIONSSTR and option have values, the NEWSTR is replicated to OPTIONSSTR for recursive loops-->
<xsl:if test= "$optionsStr!= ' and $option!= '" >
<xsl:call-template name= "Areaoptions" >
<xsl:with-param name= "Optionsstr" ><xsl:value-of select= "$newStr"/></xsl:with>
</xsl:call>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

Main idea: By composing a main classification loop into a string and then recursively intercepting the string for 2 options, if the two different options are intercepted, the option is not duplicated, whereas the recursive loop is returned. Recursion is ended until the total string is truncated and the option is not intercepted. The specific ideas are visible in the comments section of the code.

Final implementation effect:



Latest Answer:
2012.04.23: The latest Xsl:key and key () methods found in XSLT allow you to simply implement the filter results:

  code is as follows copy code

< XML version= "1.0" encoding= "UTF-8"
<xsl:stylesheet version= "1.0" xmlns:xsl= "Http://www.w3.org/1999/XSL/Transform"
    <xsl:key name= "Mainarea" match = "Rows/row" use= "area"/>
 
    <xsl:template match= "/"
         <xsl:for-each select= "Rows/row[count (. | key (' mainarea ', area) [1]) = 1]"
 & nbsp;          <xsl:value-of select= "area"/><br/>
        </xsl:for>
    </xsl:template>
</ Xsl:stylesheet>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.