在XSLT中,对除用引号引起来的所有值进行令牌化

时间:2019-06-05 04:59:01

标签: xslt xslt-2.0

我正在尝试标记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”中分离出来

这是错误的。

除引号中的值外,如何标记行中的所有值? 我似乎找不到办法。

我将不胜感激。

谢谢。

1 个答案:

答案 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), '&quot;', '')" />
        </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(., ','), '((&quot;[^&quot;]*&quot;)|([^,&quot;]*)),')/*:match/*:group/replace(., '&quot;', '')"  />
    <xsl:for-each select="$fields">
      <field>
        <xsl:value-of select="." />
      </field>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>

请注意,正则表达式组包含任何定界字段的引号,因此使用replace。它假定引号仅用于定界带有逗号的字段,而不会出现其他字符,例如在普通文本字段的中间(如果使用引号,则可能会进入一个痛苦的世界……)。