Учитывая число формы как:
ABC_12345_Q-10
Я хочу закончить с:
ABC12345
Таким образом, я должен найти положение второго подчеркивания
Обратите внимание, что нет никакого стандартного шаблона или длины ни к одному из "разделов" между символами нижнего подчеркивания (таким образом, я не могу использовать подстроку для простого устранения последнего раздела).
решения xPath 2.0 хорошо.
concat(
substring-before($s, '_'),
substring-before(substring-after($s, '_'), '_')
)
В качестве альтернативы:
string-join(tokenize($s, '_')[position() <= 2], '')
@Pavel_Minaev предоставил решения XPath 1.0 и XPath 2.0, которые работают, если заранее известно, что количество подчеркиваний равно 2.
Вот решения для более сложной проблемы, когда количество отмененных оценок не является статическим известное (может быть любым числом):
XPath 2.0 :
translate(substring($s,
1,
index-of(string-to-codepoints($s),
string-to-codepoints('_')
)[last()] -1
),
'_',
''
)
XSLT 1.0 :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="text"/>
<xsl:variable name="s" select="'ABC_12345_Q-10'"/>
<xsl:template match="/">
<xsl:call-template name="stripLast">
<xsl:with-param name="pText" select="$s"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="stripLast">
<xsl:param name="pText"/>
<xsl:param name="pDelim" select="'_'"/>
<xsl:if test="contains($pText, $pDelim)">
<xsl:value-of select="substring-before($pText, $pDelim)"/>
<xsl:call-template name="stripLast">
<xsl:with-param name="pText" select=
"substring-after($pText, $pDelim)"/>
<xsl:with-param name="pDelim" select="$pDelim"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к любому XML-документу (не используется), желаемый, правильный создается результат :
ABC12345