在每个最后一个冒号后获取值 [英] Get value after each last colon
问题描述
我需要在最后一个冒号之后获取每个数据的值.例如,我有这个文件:
I need to get the value of each data after the last colon. For example, I have this file:
<Data>
:20:PmtReferenceID000012
:21:Not used
:25: PHMNLBICXXX/Account00010203
:28c:00001/0001 (The 'c' in :28 can be either in upper or lower case)
:20:PmtReferenceID000012
:21:Not used
:25: PHMNLBICXXX/Account00010203
:28c:00001/0001 (The 'c' in :28 can be either in upper or lower case)
</Data>
我需要将 ':20:' 之后的值存储到
、':21:' 到
、':25:' 到
和 ':28c:' 到
.
I need to store the value after the ':20:' to <ABCD>
, ':21:' to <EFGH>
, ':25:' to <IJKL>
and ':28c:' to <MNOP>
.
这是我的 XSLT:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Data">
<Data>
<xsl:variable name="OneLine" select="replace(translate(.,' ', '|'),'
','')"/>
<ABCD>
<xsl:value-of select="substring-before(substring-after($OneLine, ':20:'),'|:')"/>
</ABCD>
<EFGH>
<xsl:value-of select="substring-before(substring-after($OneLine, ':21:'),'|:')"/>
</EFGH>
<IJKL>
<xsl:value-of select="substring-before(substring-after($OneLine, ':25:'),'|:')"/>
</IJKL>
<MNOP>
<xsl:value-of select="substring-before(substring-after($OneLine, ':28c:'),'|:')"/>
</MNOP>
</Data>
</xsl:template>
预期输出:
<Data>
<ABCD>PmtReferenceID000012</ABCD>
<EFGH>Not used</EFGH>
<IJKL> PHMNLBICXXX/Account00010203</IJKL>
<MNOP>00001/0001</MNOP>
</Data>
<Data>
<ABCD>PmtReferenceID000012</ABCD>
<EFGH>Not used</EFGH>
<IJKL> PHMNLBICXXX/Account00010203</IJKL>
<MNOP>00001/0001</MNOP>
</Data>
我所做的是,我首先将回车符替换为管道 ('|'),这样,如果我得到值,例如 ':20:',我将查找 '|'并将 ':20:' 之后和 '|' 之前的值子串起来.如果我要使用我所做的方法,是否有一种简单的方法可以在每个最后一个冒号之后获取值,因为键太多了?我正在考虑使用索引或位置,并存储所有键 (:20:,:21:,:25:,:28c'),以便如果下一条记录包含 ':21:' 或 ':25:' 或 ':28c',它将获得该键之前的值.但是,我不知道如何使用 xslt 做到这一点.
What I did is, I replace first the carriage return to pipe ('|'), so that, if I get the value for example the ':20:', I will look for the '|' and substring the value after the ':20:' and before the '|'. Is there an easy way on will I get the value after each last colon because there's so many keys, if I'm going to use the method that I did? I'm thinking of using an index or position, and store all the keys (:20:,:21:,:25:,:28c'), so that if the next record contains ':21:' or ':25:' or ':28c', it will get the value before that key. But, I don't have any idea on how will I do that using xslt.
非常感谢您的反馈!
谢谢,
推荐答案
我在您的原始帖子中写了这个答案,但没有发布它,因为它本质上与 zx485 发布的类似.
I wrote this answer to your original post but didn't post it because it was essentially similar to the one posted by zx485.
但是,我仍然建议使用 key 检索相应的元素名称(我也认为正则表达式可以更简单、更健壮).
However, I still recommend using a key to retrieve the corresponding element name (and I also think the regex can be simpler and more robust).
我添加了一个标记化步骤,将数据拆分为每个双换行符上的单独 包装器.
I have added a tokenizing step to split the data into separate <Data>
wrappers on every double line-feed character.
XSLT 2.0
<xsl:stylesheet version="2.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="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="map">
<name key="20">ABCD</name>
<name key="21">EFGH</name>
<name key="25">IJKL</name>
<name key="28C">MNOP</name>
</xsl:variable>
<xsl:key name="nm" match="name" use="@key" />
<xsl:template match="Data">
<xsl:for-each select="tokenize(., '\n\n')">
<Data>
<xsl:analyze-string select="." regex="^:([^:]*):(.*)$" flags="m">
<xsl:matching-substring>
<xsl:element name="{key('nm', upper-case(regex-group(1)), $map)}">
<xsl:value-of select="regex-group(2)" />
</xsl:element>
</xsl:matching-substring>
</xsl:analyze-string>
</Data>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
<小时>
演示:http://xsltransform.net/ehVYZNm
这篇关于在每个最后一个冒号后获取值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!