我正在尝试标记XML中具有逗号分隔值的行。
<xsl:variable name="lineField" select="tokenize(tag,',')" />
这很好,直到我注意到第4、5、6位的金额值被修剪或标记化,这对我的意图是错误的。
下面是CSV文件中的示例行,其中有6个值,以5个逗号分隔 金额用引号括起来
, , Amount Paid,"133,654.70 ","9,356.10 ","124,298.60 "
tokenize(tag,',')
的结果是数组中的9个元素,而不仅仅是6个
lineField[] = {'','','AmountPaid','133','654.70','9','356.10','124','298.60'};
133 从“ 133 ,654.70”中分离出来
9 与“ 9 ,356.10”分开
124 从“ 124 ,298.60”中分离出来
这是错误的。
除引号中的值外,如何标记行中的所有值? 我似乎找不到办法。
我将不胜感激。
谢谢。
答案 0 :(得分:0)
正如Martin Honnen在评论中提到的那样,您将需要在此处使用analyze-string
来匹配各个字段。
经过反复试验,我想到了这个
<xsl:template match="tag">
<xsl:copy>
<xsl:analyze-string select="concat(., ',')" regex='(("[^"]*")|([^,"]*)),'>
<xsl:matching-substring>
<field>
<xsl:value-of select="replace(regex-group(1), '"', '')" />
</field>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:copy>
</xsl:template>
或者,使用变量。...
<xsl:template match="tag">
<xsl:copy>
<xsl:variable name="fields" select="analyze-string(concat(., ','), '(("[^"]*")|([^,"]*)),')/*:match/*:group/replace(., '"', '')" />
<xsl:for-each select="$fields">
<field>
<xsl:value-of select="." />
</field>
</xsl:for-each>
</xsl:copy>
</xsl:template>
请注意,正则表达式组包含任何定界字段的引号,因此使用replace
。它假定引号仅用于定界带有逗号的字段,而不会出现其他字符,例如在普通文本字段的中间(如果使用引号,则可能会进入一个痛苦的世界……)。>