用破折号组合XSLT中的字母数字 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R17 贴片
大家好,, 请看上面的XML。我正在生成一个PDF,并编写了如下XSL代码用破折号组合XSLT中的字母数字 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R17 贴片,xslt,Xslt,大家好,, 请看上面的XML。我正在生成一个PDF,并编写了如下XSL代码 <ReferenceDesignators> <ReferenceDesignator>R1</ReferenceDesignator> <ReferenceDesignator>R2</ReferenceDesignator> <ReferenceDesignator>R3</ReferenceDesignator> <Refer
<ReferenceDesignators>
<ReferenceDesignator>R1</ReferenceDesignator>
<ReferenceDesignator>R2</ReferenceDesignator>
<ReferenceDesignator>R3</ReferenceDesignator>
<ReferenceDesignator>R4</ReferenceDesignator>
<ReferenceDesignator>R5</ReferenceDesignator>
<ReferenceDesignator>R6</ReferenceDesignator>
<ReferenceDesignator>R7</ReferenceDesignator>
<ReferenceDesignator>R8</ReferenceDesignator>
<ReferenceDesignator>R9</ReferenceDesignator>
<ReferenceDesignator>R10</ReferenceDesignator>
<ReferenceDesignator>R17</ReferenceDesignator>
<ReferenceDesignator>SMD</ReferenceDesignator>
</ReferenceDesignators>
,
所以我得到了所有用逗号分隔的值。但我希望输出为
R1-R10,R17,表面贴装
我怎样才能做到这一点,是不是可以通过正则表达式。
请帮忙
谢谢,
Manju一种可能的方法是创建一个函数,该函数可用于向值中添加1(如果值中有数字) 试试这个XSLT
<xsl:for-each-group select="ReferenceDesignator" group-starting-with="ReferenceDesignator[. != my:check(preceding-sibling::ReferenceDesignator[1])]">
,
请注意,这确实假设每个
ReferenceDesignator
由一个或多个字母组成,后面是多个数字上的零。一种可能的方法是创建一个函数,可用于将1添加到值中(如果值中有数字)
试试这个XSLT
<xsl:for-each-group select="ReferenceDesignator" group-starting-with="ReferenceDesignator[. != my:check(preceding-sibling::ReferenceDesignator[1])]">
,
请注意,这确实假设每个
引用的指定符
由一个或多个字母组成,后面是多个数字上的零。作为替代方案,这里是一个XSLT 3模板,对相邻的每个组使用:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my">
<xsl:output method="text" />
<xsl:template match="ReferenceDesignators">
<xsl:for-each-group select="ReferenceDesignator" group-starting-with="ReferenceDesignator[. != my:check(preceding-sibling::ReferenceDesignator[1])]">
<xsl:if test="position() > 1">,</xsl:if>
<xsl:value-of select="current-group()[1], current-group()[position() > 1][last()]" separator="-" />
</xsl:for-each-group>
</xsl:template>
<xsl:function name="my:check">
<xsl:param name="current" />
<xsl:variable name="number" select="if (matches($current, '.*\d+')) then xs:int(replace($current, '[A-Z]+', '')) + 1 else ''" />
<xsl:value-of select="replace($current, '\d', ''), $number" separator="" />
</xsl:function>
</xsl:stylesheet>
在XSLT 2中,可以使用连接的分组键而不是复合键:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:function name="mf:grouping-key" as="item()+">
<xsl:param name="value" as="xs:string"/>
<xsl:param name="pos" as="xs:integer"/>
<xsl:sequence
select="let $comps := analyze-string($value, '(\p{L}+)([0-9]+)?'),
$prefix := $comps//*:group[@nr = 1]/data(),
$suffix := $comps//*:group[@nr = 2]!(xs:integer(.) - $pos)
return ($prefix, $suffix)"/>
</xsl:function>
<xsl:template match="ReferenceDesignators">
<xsl:value-of separator=",">
<xsl:for-each-group select="ReferenceDesignator" composite="yes" group-adjacent="mf:grouping-key(., position())">
<xsl:sequence
select="string-join((. | current-group()[last()]), '-')"/>
</xsl:for-each-group>
</xsl:value-of>
</xsl:template>
</xsl:stylesheet>
(\p{L}+)([0-9]+)?
作为替代方案,这里有一个XSLT 3模板,对相邻的每个组使用:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my">
<xsl:output method="text" />
<xsl:template match="ReferenceDesignators">
<xsl:for-each-group select="ReferenceDesignator" group-starting-with="ReferenceDesignator[. != my:check(preceding-sibling::ReferenceDesignator[1])]">
<xsl:if test="position() > 1">,</xsl:if>
<xsl:value-of select="current-group()[1], current-group()[position() > 1][last()]" separator="-" />
</xsl:for-each-group>
</xsl:template>
<xsl:function name="my:check">
<xsl:param name="current" />
<xsl:variable name="number" select="if (matches($current, '.*\d+')) then xs:int(replace($current, '[A-Z]+', '')) + 1 else ''" />
<xsl:value-of select="replace($current, '\d', ''), $number" separator="" />
</xsl:function>
</xsl:stylesheet>
在XSLT 2中,可以使用连接的分组键而不是复合键:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:function name="mf:grouping-key" as="item()+">
<xsl:param name="value" as="xs:string"/>
<xsl:param name="pos" as="xs:integer"/>
<xsl:sequence
select="let $comps := analyze-string($value, '(\p{L}+)([0-9]+)?'),
$prefix := $comps//*:group[@nr = 1]/data(),
$suffix := $comps//*:group[@nr = 2]!(xs:integer(.) - $pos)
return ($prefix, $suffix)"/>
</xsl:function>
<xsl:template match="ReferenceDesignators">
<xsl:value-of separator=",">
<xsl:for-each-group select="ReferenceDesignator" composite="yes" group-adjacent="mf:grouping-key(., position())">
<xsl:sequence
select="string-join((. | current-group()[last()]), '-')"/>
</xsl:for-each-group>
</xsl:value-of>
</xsl:template>
</xsl:stylesheet>
(\p{L}+)([0-9]+)?
您能使用XSLT2.0(或3.0)吗?我在使用XSLT2.0。您能使用XSLT2.0(或3.0)吗?我在使用XSLT2.0。我认为(x-position())
是比(x mod position())
更可靠的分组键。如果第9位有18个,第10位有19个,那么(x mod position())
对这两项给出了不同的答案。@MichaelKay,谢谢,你说得很对,我需要更正示例。我认为(x-position())
是比(x mod position())
更可靠的分组键。如果第9位有18个,第10位有19个,那么(x mod position())
对这两个项目给出了不同的答案。@MichaelKay,谢谢,你说得很对,我需要更正样本。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="2.0">
<xsl:function name="mf:grouping-key" as="xs:string">
<xsl:param name="value" as="xs:string"/>
<xsl:param name="pos" as="xs:integer"/>
<xsl:variable name="comps" as="item()*">
<xsl:variable name="pattern" as="xs:string">(\p{L}+)([0-9]+)?</xsl:variable>
<xsl:analyze-string select="$value" regex="{$pattern}">
<xsl:matching-substring>
<xsl:sequence select="regex-group(1), regex-group(2)"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:variable name="prefix" select="$comps[1]"/>
<xsl:variable name="suffix" select="if ($comps[2] castable as xs:integer) then (xs:integer($comps[2]) - $pos) else ()"/>
<xsl:sequence
select="concat($prefix, $suffix)"/>
</xsl:function>
<xsl:template match="ReferenceDesignators">
<xsl:value-of separator=",">
<xsl:for-each-group select="ReferenceDesignator" group-adjacent="mf:grouping-key(., position())">
<xsl:sequence
select="string-join((. | current-group()[last()]), '-')"/>
</xsl:for-each-group>
</xsl:value-of>
</xsl:template>
</xsl:stylesheet>