xslt 1.0-基于分隔符对空间进行标准化/Sanitize,然后标记结果(仅限Vanilla xslt)



我有数据,我需要基于" - "对其进行标记。注意,连字符两边都有一个空格,然而,在解析了十万行之后,我注意到一些数据的连字符周围缺少空格,这破坏了我的逻辑。

我试着使用concat和substring,找到断开的连字符并添加空格,但无论我做什么,我都无法解决所有情况。我认为最好的目标是找到所有的连字符,并确保每边正好有1个空格。不过,老实说,我完全愿意接受建议。

编辑,我需要解决这个例子。我认为,在标记化中添加一个安全单词列表可能是最简单的。然而,我不知道该怎么做

<part>
<partDescription>Belden Gloves- Hi-Viz - Orange -Small</partDescription>
</part>

https://xsltfiddle.liberty-development.net/nb9PtDF/1

<root>
<!--99% of the 200k records are this first below record -->
<part>
<partDescription>Awesome Shirts - Chocolate/Black - Medium</partDescription>
</part>

<!-- However, there are a few hundred that didn't space the delimiter correctly 
this causes my token template to not function as expected-->
<part>
<partDescription>Bantam Gloves - Chocolate/Black -Medium</partDescription>
</part>
<part>
<partDescription>Belden Gloves- Black - Large</partDescription>
</part>
<part>
<partDescription>Belden Gloves - Heatshield - Red- Small</partDescription>
</part>
<part>
<partDescription>Belden Hats -Orange -Small</partDescription>
</part>
<part>
<partDescription>XSLT Jacket- Black -Small</partDescription>
</part>
</root>

当前XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
xmlns:php="http://php.net/xsl"
exclude-result-prefixes="php"
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="part">        
<item>                
<!--Struggling here :( -->
<xsl:call-template name="tokenizeDescription">
<!--<xsl:with-param name="text" select= "partDescription"/>-->
<xsl:with-param name="text" select= 
"concat( substring-before(partDescription, '- '), ' - ', 
substring-after(partDescription, '- ') )"/>

</xsl:call-template>

</item>
</xsl:template>

<!-- Parse Description as Keys  -->
<xsl:template name="tokenizeDescription">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="' - '"/>
<xsl:param name="partType"/>
<xsl:param name="keys">
<xsl:choose>
<xsl:when test="contains(partDescription, 'Heatshield')">short_name,benefit,color,size,</xsl:when>
<xsl:otherwise>short_name,color,size,</xsl:otherwise>
</xsl:choose>
</xsl:param>

<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="tokenizeDescription">
<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>

预期结果

<?xml version="1.0" encoding="UTF-8"?>
<item>
<short_name>Awesome Shirts</short_name>
<color>Chocolate/Black</color>
<size>Medium</size>
</item>
<item>
<short_name>Bantam Gloves</short_name>
<color>Chocolate/Black</color>
<size>Medium</size>
</item>
<item>
<short_name>Belden Gloves</short_name>
<color>Black</color>
<size>Large</size>
</item>
<item>
<short_name>Belden Gloves</short_name>
<benefit>Heatshield</benefit>
<color>Red</color>
<size>Small</size>
</item>
<item>
<short_name>Belden Hats</short_name>
<color>Orange</color>
<size>Small</size>
</item>
<item>
<short_name>XSLT Jacket</short_name>
<color>Black</color>
<size>Small</size>
</item>

实际结果

<?xml version="1.0" encoding="UTF-8"?>
<item>
<short_name>Awesome Shirts </short_name>
<color>Chocolate/Black</color>
<size>Medium</size>
</item>
<item>
<short_name>Bantam Gloves </short_name>
<color>Chocolate/Black -Medium</color>
</item>
<item>
<short_name>Belden Gloves</short_name>
<color>Black</color>
<size>Large</size>
</item>
<item>
<short_name>Belden Gloves </short_name>
<benefit>Heatshield</benefit>
<color>Red- Small</color>
</item>
<item>
<short_name/>
<color/>
</item>
<item>
<short_name>XSLT Jacket</short_name>
<color>Black -Small</color>
</item>

这可能会有所帮助。如果你有问题,请告诉我。

<xsl:template match="node()">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="partDescription">
<xsl:variable name="nodes">
<xsl:call-template name="getNodesFromDelimitedList">
<xsl:with-param name="inStrList" select="."/>
<xsl:with-param name="delimiter" select="'-'"/>
</xsl:call-template>
</xsl:variable>  
<!-- *** NOTE *** Make sure you use your prefix to create the node set, not msxml.  -->
<xsl:variable name="nodeList" select="msxml:node-set($nodes)"/>
<xsl:choose>
<xsl:when test="contains(., 'Heatshield')">
<xsl:element name="item">
<xsl:element name="short_name">
<xsl:value-of select="$nodeList/element[1]"/>
</xsl:element>
<xsl:element name="benefit">
<xsl:value-of select="$nodeList/element[2]"/>
</xsl:element>

<xsl:element name="color">
<xsl:value-of select="$nodeList/element[3]"/>
</xsl:element>
<xsl:element name="size">
<xsl:value-of select="$nodeList/element[4]"/>
</xsl:element>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="item">
<xsl:element name="short_name">
<xsl:value-of select="$nodeList/element[1]"/>
</xsl:element>

<xsl:element name="color">
<xsl:value-of select="$nodeList/element[2]"/>
</xsl:element>
<xsl:element name="size">
<xsl:value-of select="$nodeList/element[3]"/>
</xsl:element>
</xsl:element>
</xsl:otherwise>          
</xsl:choose>
</xsl:template>

<xsl:template name="getNodesFromDelimitedList">
<!-- Delimited string with one or more delimiters.  -->
<xsl:param name="inStrList"/>
<!-- The delimiter. -->
<xsl:param name="delimiter" select="'|'"/>
<xsl:choose>
<xsl:when test="contains($inStrList,$delimiter)">
<!-- Get the first element from the list.  -->
<xsl:variable name="element" select="substring-before($inStrList,$delimiter)"/>
<!-- Put the element in the list.  -->
<xsl:element name="element">
<xsl:value-of select="normalize-space($element)"/>
</xsl:element>
<!-- Call template to process the next element. -->
<xsl:call-template name="getNodesFromDelimitedList">
<xsl:with-param name="inStrList" select="substring-after($inStrList,$delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- Put the element in the list.  -->
<xsl:element name="element">
<xsl:value-of select="normalize-space($inStrList)"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

相关内容

最新更新