XSLT 1.0,使用身份转换,多个模板无法匹配 [英] XSLT 1.0, Using Identity Transform, with multiple templates fails to match

查看:20
本文介绍了XSLT 1.0,使用身份转换,多个模板无法匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

哇,自从大约 15 年前介绍编程以来,我就没有问过这么多问题了,这个 XSLT 的东西让我大吃一惊!我一直在学习使用 Identity Transform,获取字符串并根据分隔符将其分解为节点.我按预期工作,但是当我将它与我的其余逻辑结合起来时,它就会中断.我认为这与我对元素本身的选择器有关.我为自己找到了一个身份转换的基本示例而感到自豪.我一直在工作和学习,从这里开始.XSLT 1.0 - 使用 Vanilla XSLT 1.0 或 PHP XSLT 的节点中值唯一性的输出计数 我认为选择器和操作顺序将是我需要考虑的下一件事情

Wow, I haven't asked this many questions since, intro to programming some 15 years ago, this XSLT stuff is kicking me! I've been learning to work with Identity Transform, to take a string and break it into nodes based on a delimiter. Which I have working as expected, but when I combine it with the rest of my logic it breaks. I'm thinking it has to do with my selectors on the elements themselves. I'm just proud of myself that I figured out a working basic example of Identity transform. I've been working and learning through phases, with the original starting here. XSLT 1.0 - Output Count of Value Uniqueness in a Node with Vanilla XSLT 1.0 or PHP XSLT I think selectors and order of operations are going to be the next things I need to wrap my head around.

任何帮助将不胜感激.:)

Any help would be greatly appreciated. :)

源数据已编辑不要使用,因为我最初提供了有缺陷的数据,并在下面添加了更新的数据.

Source Data EDITED Don't use, as I supplied flawed data originally, and added updated data below.

<root>
  <part>
    <partNumber>33020780</partNumber>
    <punctuatedPartNumber>3302-0780</punctuatedPartNumber>
    <partStatusDescription>STANDARD</partStatusDescription>
    <partDescription>Women's Hooligan Glove - Black - 2XL</partDescription>
    <unitOfMeasure>Pair</unitOfMeasure>
    <brandName>ICON</brandName>
    <supplierNumber></supplierNumber>
    <specialInstructions/>
    <baseDealerPrice>15.0000</baseDealerPrice>
    <yourDealerPrice>15.0000</yourDealerPrice>
    <baseRetailPrice>30.0000</baseRetailPrice>
    <originalRetailPrice>30.0000</originalRetailPrice>
    <partImage>http://asset.lemansnet.com/z/L0UvOS8zL0U5M0JDMzM4LUNEMDAtNDhGNi1CMjQzLTJCM0U3ODBCQzU0NCwvRC85LzEvRDkxQUQ1ODQtQjU0Ny00MTYzLUIxNDgtMzk3MTMwOEU2N0U5</partImage>
    <productId>1967508881</productId>
    <productName>Women's Hooligan™ Gloves</productName>
    <productImage>http://asset.lemansnet.com/z/bWVkaWEvYzY1Y2JiYzctYTk4OC00OTY0LWJlYTEtNzYzZDFiYmQ4NzBlLC9FLzkvMy9FOTNCQzMzOC1DRDAwLTQ4RjYtQjI0My0yQjNFNzgwQkM1NDQsejJodWhwWVN1cGc=</productImage>
    <bullet1>Durable nylon/synthetic suede construction</bullet1>
    <bullet2>AxSuede Laredo palm</bullet2>
    <bullet3>Thermoplastic knuckle armor for durable, flexible protection</bullet3>
    <bullet4>Ram air finger inserts help keep hands cool</bullet4>
    <bullet5>Snap secures gloves together when not in use</bullet5>
    <bullet6/>
    <bullet7/>
    <bullet8/>
    <bullet9/>
    <bullet10/>
    <bullet11/>
    <bullet12/>
    <bullet13/>
    <bullet14/>
    <bullet15/>
    <bullet16/>
    <bullet17/>
    <bullet18/>
    <bullet19/>
    <bullet20/>
    <bullet21/>
    <bullet22/>
    <bullet23/>
    <bullet24/>
  </part>
  <part>
    <partNumber>33020783</partNumber>
    <punctuatedPartNumber>3302-0783</punctuatedPartNumber>
    <partStatusDescription>STANDARD</partStatusDescription>
    <partDescription>Women's Hooligan Glove - Pink - Medium</partDescription>
    <unitOfMeasure>Pair</unitOfMeasure>
    <brandName>ICON</brandName>
    <supplierNumber></supplierNumber>
    <specialInstructions/>
    <baseDealerPrice>15.0000</baseDealerPrice>
    <yourDealerPrice>15.0000</yourDealerPrice>
    <baseRetailPrice>30.0000</baseRetailPrice>
    <originalRetailPrice>30.0000</originalRetailPrice>
    <partImage>http://asset.lemansnet.com/z/L0UvRi8zL0VGMzE4NzU3LTZCNDAtNDUyNi1CMjY3LTRBMzYzNTI2RkU1RSwvMC9EL0MvMERDQ0NCQTktMEVEOC00QzI0LThBRDYtOTRDNzVCQUU5NUVC</partImage>
    <productId>1967508881</productId>
    <productName>Women's Hooligan™ Gloves</productName>
    <productImage>http://asset.lemansnet.com/z/bWVkaWEvYzY1Y2JiYzctYTk4OC00OTY0LWJlYTEtNzYzZDFiYmQ4NzBlLC9FLzkvMy9FOTNCQzMzOC1DRDAwLTQ4RjYtQjI0My0yQjNFNzgwQkM1NDQsejJodWhwWVN1cGc=</productImage>
    <bullet1>Durable nylon/synthetic suede construction</bullet1>
    <bullet2>AxSuede Laredo palm</bullet2>
    <bullet3>Thermoplastic knuckle armor for durable, flexible protection</bullet3>
    <bullet4>Ram air finger inserts help keep hands cool</bullet4>
    <bullet5>Snap secures gloves together when not in use</bullet5>
    <bullet6/>
    <bullet7/>
    <bullet8/>
    <bullet9/>
    <bullet10/>
    <bullet11/>
    <bullet12/>
    <bullet13/>
    <bullet14/>
    <bullet15/>
    <bullet16/>
    <bullet17/>
    <bullet18/>
    <bullet19/>
    <bullet20/>
    <bullet21/>
    <bullet22/>
    <bullet23/>
    <bullet24/>
  </part>
</root>

工作身份转换

<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="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="partDescription" name="tokenize">
        <xsl:param name="text" select="."/>
        <xsl:param name="delimiter" select="' - '"/>
        <xsl:param name="keys" select="'short_name,color,size'"/>
        <xsl:element name="{substring-before($keys, ',')}">
            <xsl:value-of select="substring-before(concat($text, $delimiter), $delimiter)" />
        </xsl:element>
        <xsl:if test="contains($text, $delimiter)">
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                <xsl:with-param name="keys" select="substring-after($keys, ',')"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

Broken Full Example,当我说break时,结果只是

Broken Full Example, when I say broken the result is just <items/>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="part-by-product" match="part" use="productId" />
    <xsl:strip-space elements="*"/>

    <!-- Transform Data  -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- Parse Description as Keys  -->
    <xsl:template match="partDescription" name="tokenize">
        <xsl:param name="text" select="."/>
        <xsl:param name="delimiter" select="' - '"/>
        <xsl:param name="keys" select="'short_name,color,size'"/>
        <xsl:element name="{substring-before($keys, ',')}">
            <xsl:value-of select="substring-before(concat($text, $delimiter), $delimiter)" />
        </xsl:element>
        <xsl:if test="contains($text, $delimiter)">
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                <xsl:with-param name="keys" select="substring-after($keys, ',')"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template match="/root">
        <xsl:element name="items">
            <xsl:for-each select="part[supplierNumber/text() and partStatusDescription != 'DISCONTINUED']">
                <xsl:element name="item">
                    
                    <!-- finish -->
                    <xsl:choose>
                        <xsl:when test="contains(partDescription, 'Black')">
                            <finish>Black</finish>
                        </xsl:when>
                        <xsl:when test="contains(partDescription, 'Flat Back')">
                            <finish>Flat Back</finish>
                        </xsl:when>
                        <xsl:when test="contains(partDescription, 'Chrome')">
                            <finish>Chrome</finish>
                        </xsl:when>
                    </xsl:choose>
                    
                    <!-- size -->
                    <xsl:call-template name="find-size">
                        <xsl:with-param name="text" select="partDescription"/>
                    </xsl:call-template>

                    <!-- Check if a Product should be configurable -->
                    <xsl:copy-of select="partNumber | productId"/>
                    <!-- check productId uniqueness -->
                    <xsl:if test="count(key('part-by-product', productId)) > 1">
                        <configurableId>
                            <xsl:value-of select="productId"/>
                        </configurableId>
                    </xsl:if>

                    <xsl:element name="name">
                         <xsl:value-of select="concat(brandName,' ',productName)"/>
                    </xsl:element>
                    <punctuatedPartNumber>
                        <xsl:value-of select="punctuatedPartNumber"/>
                    </punctuatedPartNumber>
                     <xsl:element name="is_in_stock">
                        <xsl:if test="partStatusDescription = 'STANDARD'">
                                <xsl:value-of select="1"/>
                        </xsl:if>
                        <xsl:if test="partStatusDescription != 'STANDARD'">
                            <xsl:value-of select="0"/>
                        </xsl:if>    
                    </xsl:element>
                    <partDescription>
                        <xsl:value-of select="partDescription"/>
                    </partDescription>
                    <unitOfMeasure>
                        <xsl:value-of select="unitOfMeasure"/>
                    </unitOfMeasure>
                    <brandName>
                        <xsl:value-of select="brandName"/>
                    </brandName>
                    <supplierNumber>
                        <xsl:value-of select="supplierNumber"/>
                    </supplierNumber>
                    <specialInstructions>
                        <xsl:value-of select="specialInstructions"/>
                    </specialInstructions>
                    <xsl:element name="price">
                        <xsl:value-of select="(originalRetailPrice * 100) div 100"/>
                    </xsl:element>
                    <xsl:element name="special_price">
                        <xsl:if test="baseRetailPrice  &lt; originalRetailPrice">
                            <xsl:value-of select="baseRetailPrice"/>
                        </xsl:if>
                    </xsl:element>
                    <partImage>
                        <xsl:value-of select="partImage"/>
                    </partImage>
                    <productName>
                        <xsl:value-of select="productName"/>
                    </productName>
                    <productImage>
                        <xsl:value-of select="productImage"/>
                    </productImage>
                    <bullet1>
                        <xsl:value-of select="bullet1"/>
                    </bullet1>
                    <bullet2>
                        <xsl:value-of select="bullet2"/>
                    </bullet2>
                    <bullet3>
                        <xsl:value-of select="bullet3"/>
                    </bullet3>
                    <bullet4>
                        <xsl:value-of select="bullet4"/>
                    </bullet4>

                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

    <xsl:template name="find-size">
        <xsl:param name="text"/>
        <xsl:param name="delimiter" select="' '"/>
        <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
        <xsl:choose>
            <xsl:when test="starts-with(translate($token, '123456789', '000000000'), '0')">
                <size>
                    <xsl:value-of select="$token"/>
                </size>
            </xsl:when>
            <xsl:when test="contains($text, $delimiter)">
                <!-- recursive call -->
                <xsl:call-template name="find-size">
                    <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                </xsl:call-template>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

******************************** 编辑如下 ******************************

***************************** EDITED BELOW ******************************

更新的数据样本

我提供了样本数据,这不会发生意外,这也解释了为什么我只收到原始节点元素.但是,即使修复了我的愚蠢错误,我的代码组合也不起作用

I provided sample data, that would have never worked on accident, which also explains why I only received the original node element. However, even after fixing my stupid mistake, my combination of codes does not work

<root>
  <part>
    <partNumber>33020576</partNumber>
    <punctuatedPartNumber>3302-0576</punctuatedPartNumber>
    <partStatusDescription>STANDARD</partStatusDescription>
    <partDescription>Stella SP-8 V2 Gloves - Black/White/Pink - Large</partDescription>
    <unitOfMeasure>Pair</unitOfMeasure>
    <brandName>ALPINESTARS (ROAD)</brandName>
    <supplierNumber>3518317-1239-L</supplierNumber>
    <specialInstructions/>
    <baseDealerPrice>68.0000</baseDealerPrice>
    <yourDealerPrice>68.0000</yourDealerPrice>
    <baseRetailPrice>99.9500</baseRetailPrice>
    <originalRetailPrice>99.9500</originalRetailPrice>
    <partImage>http://asset.lemansnet.com/z/L0EvRC84L0FEODhFNTI1LTBGRjItNEY3NC1CRTBDLTg4RkNBNjdCREVFQw==</partImage>
    <productId>0975297251</productId>
    <productName>Stella SP-8 V2 Leather Gloves</productName>
    <productImage>http://asset.lemansnet.com/z/LzcvMC9CLzcwQkJGNjJGLURDMDUtNDY0RC1BQ0YzLTQxN0FEQ0E3RDgwNCxtZWRpYS82OGFiOGQ5YS0wMDhiLTQ1NDctOGExMC1jZTBhNGU2MmUyNzQsbWVkaWEvYzZlODQwNDEtZTViMy00YTExLWJjYjUtODJiMDQ5NmI4OGZl</productImage>
    <bullet1>Tall, relaxed sport glove</bullet1>
    <bullet2>Premium, full-grain leather construction is durable and offers excellent abrasion resistance.</bullet2>
    <bullet3>An innovative microfiber and Polyurethane coated (PU) grip insert strategically position on palm and thumb for excellent levels of grip control and durability.</bullet3>
    <bullet4>Chassis is profiled for female specific fit and Alpinestars’ exclusive ergonomic stretch insert between palm and thumb offers improved range of hand movement and greater sensitivity while operating the bike controls.</bullet4>
    <bullet5>Incorporates premium quality suede palm and landing reinforcement for grip, control and durability.</bullet5>
    <bullet6>Alpinestars’ patented third and fourth finger bridge prevents seam failure and finger separation in the event of a slide.</bullet6>
    <bullet7>Excellent repeated impact performance offered by an advanced over-molded polymer knuckle protector.</bullet7>
    <bullet8>Ethylene vinyl acetate (EVA) foam padding reinforcements on thumb, wrist, back of hand, finger and palm for comfort and abrasion performance.</bullet8>
    <bullet9>Perforated leather cuff, plus perforated finger sidewalls for superb breathability.</bullet9>
    <bullet10>Velcro cuff closure, plus elasticized wrist design for secure, personalized fit.</bullet10>
    <bullet11>Pre-shaped fingers and external seams for comfort and exceptional feel.</bullet11>
    <bullet12>Printed and embroidered logos on wrist and fingers, plus heat stamped logo on knuckle.</bullet12>
    <bullet13>Touchscreen compatible fingertip on index finger for use with touch screen devices.</bullet13>
    <bullet14/>
    <bullet15/>
    <bullet16/>
    <bullet17/>
    <bullet18/>
    <bullet19/>
    <bullet20/>
    <bullet21/>
    <bullet22/>
    <bullet23/>
    <bullet24/>
  </part>
  <part>
    <partNumber>33020577</partNumber>
    <punctuatedPartNumber>3302-0577</punctuatedPartNumber>
    <partStatusDescription>STANDARD</partStatusDescription>
    <partDescription>Stella SP-8 V2 Gloves - Black/White/Pink - XL</partDescription>
    <unitOfMeasure>Pair</unitOfMeasure>
    <brandName>ALPINESTARS (ROAD)</brandName>
    <supplierNumber>3518317-1239-XL</supplierNumber>
    <specialInstructions/>
    <baseDealerPrice>68.0000</baseDealerPrice>
    <yourDealerPrice>68.0000</yourDealerPrice>
    <baseRetailPrice>99.9500</baseRetailPrice>
    <originalRetailPrice>99.9500</originalRetailPrice>
    <partImage>http://asset.lemansnet.com/z/L0EvRC84L0FEODhFNTI1LTBGRjItNEY3NC1CRTBDLTg4RkNBNjdCREVFQw==</partImage>
    <productId>0975297251</productId>
    <productName>Stella SP-8 V2 Leather Gloves</productName>
    <productImage>http://asset.lemansnet.com/z/LzcvMC9CLzcwQkJGNjJGLURDMDUtNDY0RC1BQ0YzLTQxN0FEQ0E3RDgwNCxtZWRpYS82OGFiOGQ5YS0wMDhiLTQ1NDctOGExMC1jZTBhNGU2MmUyNzQsbWVkaWEvYzZlODQwNDEtZTViMy00YTExLWJjYjUtODJiMDQ5NmI4OGZl</productImage>
    <bullet1>Tall, relaxed sport glove</bullet1>
    <bullet2>Premium, full-grain leather construction is durable and offers excellent abrasion resistance.</bullet2>
    <bullet3>An innovative microfiber and Polyurethane coated (PU) grip insert strategically position on palm and thumb for excellent levels of grip control and durability.</bullet3>
    <bullet4>Chassis is profiled for female specific fit and Alpinestars’ exclusive ergonomic stretch insert between palm and thumb offers improved range of hand movement and greater sensitivity while operating the bike controls.</bullet4>
    <bullet5>Incorporates premium quality suede palm and landing reinforcement for grip, control and durability.</bullet5>
    <bullet6>Alpinestars’ patented third and fourth finger bridge prevents seam failure and finger separation in the event of a slide.</bullet6>
    <bullet7>Excellent repeated impact performance offered by an advanced over-molded polymer knuckle protector.</bullet7>
    <bullet8>Ethylene vinyl acetate (EVA) foam padding reinforcements on thumb, wrist, back of hand, finger and palm for comfort and abrasion performance.</bullet8>
    <bullet9>Perforated leather cuff, plus perforated finger sidewalls for superb breathability.</bullet9>
    <bullet10>Velcro cuff closure, plus elasticized wrist design for secure, personalized fit.</bullet10>
    <bullet11>Pre-shaped fingers and external seams for comfort and exceptional feel.</bullet11>
    <bullet12>Printed and embroidered logos on wrist and fingers, plus heat stamped logo on knuckle.</bullet12>
    <bullet13>Touchscreen compatible fingertip on index finger for use with touch screen devices.</bullet13>
    <bullet14/>
    <bullet15/>
    <bullet16/>
    <bullet17/>
    <bullet18/>
    <bullet19/>
    <bullet20/>
    <bullet21/>
    <bullet22/>
    <bullet23/>
    <bullet24/>
  </part>
</root>

推荐答案

好吧,在一个重大错误之后,我过滤了我的数据,并使用了本来会被过滤掉的样本数据.然后,学习,一个关键的部分,你在使用模板匹配"时必须小心和周到.通过我对以下内容的原始使用

Well, after a major mistake, of filtering my data, and using sample data that would have been filtered out. Then, learning, a key piece, that you have to be careful and thoughtful when you use "template matching" through my original use of the following

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

所以,我最终要做的是转换,从尝试匹配模板级别的所有内容,而是创建一个基本函数,该函数将节点作为参数并返回标记化的结果.同时,我当然知道有更有效的方法来实现我的目标,而且我的 XSLT 代码看起来像是由孩子写的,希望有人能从我的挣扎中学习.

So, what I ended up having to do was to convert, from trying to match everything on the template level, and rather create an essential function, that took a node as a parameter and returned back the tokenized result. While, I definitely know there are more efficient ways to accomplish my goal, and my XSLT code looks like it was written by a child, hopefully, someone can learn from my struggles.

为便于阅读而缩短的版本.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="part-by-product" match="part" use="productId" />
    <xsl:strip-space elements="*"/>

    <xsl:template match="/root">
        <xsl:element name="items">
            <xsl:for-each select="part[supplierNumber/text() and partStatusDescription != 'DISCONTINUED']">
                <xsl:element name="item">
                    
                    <!-- Call the custom template, and pass the node partDescription to the template -->
                    <xsl:call-template name="tokenize">
                        <xsl:with-param name="text" select="partDescription"/>
                    </xsl:call-template>

                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

    <!-- A template that accepts a node with text passesd as a select  -->
    <xsl:template name="tokenize">
        <xsl:param name="text"/>
        <xsl:param name="delimiter" select="' - '"/>
        <xsl:param name="keys" select="'name,color,size,configurable1,configurable2'"/>
        <xsl:element name="{substring-before($keys, ',')}">
            <xsl:value-of select="substring-before(concat($text, $delimiter), $delimiter)" />
        </xsl:element>
        <xsl:if test="contains($text, $delimiter)">
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                <xsl:with-param name="keys" select="substring-after($keys, ',')"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

我的预期结果 基于完成的示例,我将在此之后分享

<items>
    <item>
        <!-- This was the main goal this task, and what the above sample completes  -->
        <name>SP-8 V2 Gloves</name>
        <color>Black/White/Yellow</color>
        <size>3XL</size>
        <!-- The rest of the result that can be viewed by running the complete XSTL template -->
        <finish>Black</finish>
        <size>3XL</size>
        <partNumber>33012993</partNumber>
        <productId>0067377912</productId>
        <name>ALPINESTARS (ROAD) SP-8 V2 Gloves</name>
        <punctuatedPartNumber>3301-2993</punctuatedPartNumber>
        <is_in_stock>1</is_in_stock>
        <partDescription>SP-8 V2 Gloves - Black/White/Yellow - 3XL</partDescription>
        <unitOfMeasure>Pair</unitOfMeasure>
        <brandName>ALPINESTARS (ROAD)</brandName>
        <supplierNumber>3558317-125-3X</supplierNumber>
        <specialInstructions/>
        <price>99.95</price>
        <special_price/>
        <partImage>http://asset.lemansnet.com/z/LzkvNy9FLzk3RUYyQTg3LTM4QTItNDZEQy1CNzE2LThGMjNEQjQxNzgzOA==</partImage>
        <productName>SP-8 V2 Gloves</productName>
        <productImage>http://asset.lemansnet.com/z/L0UvRS9FL0VFRUEwQzRCLUZCRDktNDUzQS1CMTg3LUVCMTY2OUM5N0ZDQywvRi8yL0MvRjJDQjRERTMtQUM2MC00M0ZCLUFERDktMzE0NTA4QTIxQjcyLC8zLzAvNy8zMDdGRTEzMy0zMUFFLTQzQ0ItOTM3MC00NzY1OEI3RUM4MUEsbWVkaWEvNjhhYjhkOWEtMDA4Yi00NTQ3LThhMTAtY2UwYTRlNjJlMjc0LG1lZGlhL2M2ZTg0MDQxLWU1YjMtNGExMS1iY2I1LTgyYjA0OTZiODhmZQ==</productImage>
        <bullet1>Premium, full-grain leather construction is durable and offers excellent abrasion resistance</bullet1>
        <bullet2>An innovative microfiber and Polyurethane (PU) grip insert strategically position on palm and thumb</bullet2>
        <bullet3>Alpinestars’ exclusive ergonomic stretch insert between palm and thumb</bullet3>
        <bullet4>Premium quality suede palm and landing reinforcement.</bullet4>
    </item>
</items>

基于我的原始示例的完整版本

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="part-by-product" match="part" use="productId" />
    <xsl:strip-space elements="*"/>

    <xsl:template match="/root">
        <xsl:element name="items">
            <xsl:for-each select="part[supplierNumber/text() and partStatusDescription != 'DISCONTINUED']">
                <xsl:element name="item">
                    
                    <xsl:call-template name="tokenize">
                        <xsl:with-param name="text" select="partDescription"/>
                    </xsl:call-template>

                    <!-- finish -->
                    <xsl:choose>
                        <xsl:when test="contains(partDescription, 'Black')">
                            <finish>Black</finish>
                        </xsl:when>
                        <xsl:when test="contains(partDescription, 'Flat Back')">
                            <finish>Flat Back</finish>
                        </xsl:when>
                        <xsl:when test="contains(partDescription, 'Chrome')">
                            <finish>Chrome</finish>
                        </xsl:when>
                    </xsl:choose>
                    
                    <!-- size -->
                    <xsl:call-template name="find-size">
                        <xsl:with-param name="text" select="partDescription"/>
                    </xsl:call-template>

                    <!-- Check if a Product should be configurable -->
                    <xsl:copy-of select="partNumber | productId"/>
                    <!-- check productId uniqueness -->
                    <xsl:if test="count(key('part-by-product', productId)) > 1">
                        <configurableId>
                            <xsl:value-of select="productId"/>
                        </configurableId>
                    </xsl:if>

                    <xsl:element name="name">
                         <xsl:value-of select="concat(brandName,' ',productName)"/>
                    </xsl:element>
                    <punctuatedPartNumber>
                        <xsl:value-of select="punctuatedPartNumber"/>
                    </punctuatedPartNumber>
                     <xsl:element name="is_in_stock">
                        <xsl:if test="partStatusDescription = 'STANDARD'">
                                <xsl:value-of select="1"/>
                        </xsl:if>
                        <xsl:if test="partStatusDescription != 'STANDARD'">
                            <xsl:value-of select="0"/>
                        </xsl:if>    
                    </xsl:element>
                    <partDescription>
                        <xsl:value-of select="partDescription"/>
                    </partDescription>
                    <unitOfMeasure>
                        <xsl:value-of select="unitOfMeasure"/>
                    </unitOfMeasure>
                    <brandName>
                        <xsl:value-of select="brandName"/>
                    </brandName>
                    <supplierNumber>
                        <xsl:value-of select="supplierNumber"/>
                    </supplierNumber>
                    <specialInstructions>
                        <xsl:value-of select="specialInstructions"/>
                    </specialInstructions>
                    <xsl:element name="price">
                        <xsl:value-of select="(originalRetailPrice * 100) div 100"/>
                    </xsl:element>
                    <xsl:element name="special_price">
                        <xsl:if test="baseRetailPrice  &lt; originalRetailPrice">
                            <xsl:value-of select="baseRetailPrice"/>
                        </xsl:if>
                    </xsl:element>
                    <partImage>
                        <xsl:value-of select="partImage"/>
                    </partImage>
                    <productName>
                        <xsl:value-of select="productName"/>
                    </productName>
                    <productImage>
                        <xsl:value-of select="productImage"/>
                    </productImage>
                    <bullet1>
                        <xsl:value-of select="bullet1"/>
                    </bullet1>
                    <bullet2>
                        <xsl:value-of select="bullet2"/>
                    </bullet2>
                    <bullet3>
                        <xsl:value-of select="bullet3"/>
                    </bullet3>
                    <bullet4>
                        <xsl:value-of select="bullet4"/>
                    </bullet4>

                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

    <!-- Parse Description as Keys  -->
    <xsl:template name="tokenize">
        <xsl:param name="text"/>
        <xsl:param name="delimiter" select="' - '"/>
        <xsl:param name="keys" select="'name,color,size,configurable1,configurable2'"/>
        <xsl:element name="{substring-before($keys, ',')}">
            <xsl:value-of select="substring-before(concat($text, $delimiter), $delimiter)" />
        </xsl:element>
        <xsl:if test="contains($text, $delimiter)">
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                <xsl:with-param name="keys" select="substring-after($keys, ',')"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <!-- Size Template Engine -->
    <xsl:template name="find-size">
        <xsl:param name="text"/>
        <xsl:param name="delimiter" select="' '"/>
        <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
        <xsl:choose>
            <xsl:when test="starts-with(translate($token, '123456789', '000000000'), '0')">
                <size>
                    <xsl:value-of select="$token"/>
                </size>
            </xsl:when>
            <xsl:when test="contains($text, $delimiter)">
                <!-- recursive call -->
                <xsl:call-template name="find-size">
                    <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                </xsl:call-template>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

这篇关于XSLT 1.0,使用身份转换,多个模板无法匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆