在XSL中用逗号替换逗号

时间:2016-09-22 10:27:09

标签: xml csv xslt

我有一个XSLT,用于将CSV转换为XML。 csv的第二列包含数字,例如5,0000

我需要的是将这个数字转换为5.0000甚至更好,只需5.意味着:用a替换。将是一种可能性或切掉十进制符号及其后的任何内容。

我一直在尝试使用translate(),format-number(),number()几个小时,考虑到我在googeling和在论坛中搜索时发现的一切。不幸的是,到目前为止我还没有成功。无论我尝试什么,我不断收到的唯一错误信息是由于错误而无法编译样式表。据我所知,调试是不可能的,因为输入文件是CSV而不是XML 有人可以帮帮我吗?

请参阅下面的输入示例(CSV)和XSL(要更改的变量称为testAmount):

9612045901;5,000;Stk.;SomeText 1;M;72,04
5-10495;1,000;Stk.;SomeText 2;M;5,93
9612045901;5,000;Stk.;SomeText 3;72,04
5-10495;1,000;Stk.;SomeText 4;M;5,93


<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="fn" exclude-result-prefixes="xs fn">
<xsl:output indent="yes" encoding="UTF-8" />
<xsl:param name="csvFile"/>

<!-- 
Constants
-->
<xsl:variable name="V_ITEM_POS" select="number(1)" />
<xsl:variable name="V_ITEM_DESC_POS" select="number(4)" />
<xsl:variable name="V_AMOUNT_POS" select="number(2)" />
<xsl:variable name="V_ZONE">ZONE1</xsl:variable>
<xsl:variable name="V_PRIORITY">9</xsl:variable>
<!--  
  EVENTUELL SHPG & RECV für IBD & OBD UNTERSCHEIDEN !!! 
-->
<xsl:variable name="V_IBD_TYPE_ID">SHPG</xsl:variable>


 <!--
MAIN
-->
<xsl:template match="/" name="main">
  <xsl:variable name="csv" select="unparsed-text($csvFile)" />
  <xsl:variable name="lines" select="tokenize($csv, '&#xA;')" as="xs:string+" />
  <xsl:variable name="orderNumber" select="format-dateTime(current-dateTime(), '[Y0001][M01][D01][H01][m01][s01][f0001]')" />
  <!--

  Determine inbound or outbound order 

  positiv amound will create an inbound order
  negative amound will create an outbound order

  Test at first value line
  -->
  <xsl:for-each select="$lines">
     <xsl:variable name="rowPos" select="position()" />
     <xsl:if test="$rowPos = 1">
        <xsl:variable name="testLineItems" select="tokenize(., ';')" />
        <xsl:variable name="testAmount" select="number($testLineItems[$V_AMOUNT_POS])" />
        <!--
            INBOUND DELIVERY
        -->
        <xsl:if test="$testAmount &lt; 0">
           <xsl:call-template name="TMPL_INBOUND_DELIVERY">
              <xsl:with-param name="in_lines" select="$lines" />
              <xsl:with-param name="in_orderNumber" select="$orderNumber" />
           </xsl:call-template>
        </xsl:if>
        <!--
            OUTBOUND DELIVERY
        -->
        <xsl:if test="$testAmount &gt; 0">
           <xsl:call-template name="TMPL_OUTBOUND_DELIVERY">
              <xsl:with-param name="in_lines" select="$lines" />
              <xsl:with-param name="in_orderNumber" select="$orderNumber" />
           </xsl:call-template>
        </xsl:if>

     </xsl:if>
  </xsl:for-each>
</xsl:template>
<!--

 INBOUND DELIVERY TEMPLATE
-->
<xsl:template name="TMPL_INBOUND_DELIVERY">
  <xsl:param name="in_lines" />
  <xsl:param name="in_orderNumber" />
  <DI_TELEGRAM>
     <HEADER>
        <FULL>
           <HEADER_SOURCE>HOST</HEADER_SOURCE>
           <HEADER_DESTINATION>WAMAS</HEADER_DESTINATION>
           <HEADER_SEQUENCE>1</HEADER_SEQUENCE>
           <HEADER_RECORDTYPENAME>LOGIMATIBD00001</HEADER_RECORDTYPENAME>
        </FULL>
     </HEADER>
     <BODY>
        <LogimatIbdGroup>
           <LOGIMATIBD00001>
              <InboundDelivery_ibdNo>
                 <xsl:value-of select="$in_orderNumber" />
              </InboundDelivery_ibdNo>
              <InboundDelivery_priority>
                 <xsl:value-of select="$V_PRIORITY" />
              </InboundDelivery_priority>
              <InboundDelivery_deliveryNoteNo></InboundDelivery_deliveryNoteNo>
              <InboundDelivery_type_ibdTypeId>
                 <xsl:value-of select="$V_IBD_TYPE_ID" />
              </InboundDelivery_type_ibdTypeId>
              <InboundDelivery_externalRef></InboundDelivery_externalRef>
              <InboundDelivery_unloadingPoint_area_areaId>
                 <xsl:value-of select="$V_ZONE" />
              </InboundDelivery_unloadingPoint_area_areaId>
              <LOGIMATIBD00001_subList>
                 <xsl:for-each select="$in_lines">
                    <xsl:variable name="lineItems" select="tokenize(., ';')" />
                       <!-- remove empty lines -->
                       <xsl:if test="number($lineItems[$V_AMOUNT_POS])!= number(0)">
                          <xsl:call-template name="TMPL_INBOUND_DELIVERY_LINE">
                             <xsl:with-param name="in_orderNumber" select="$in_orderNumber" />
                             <xsl:with-param name="in_sysPartnerLine" select="position() -1" />
                             <xsl:with-param name="in_itemNumber" select="$lineItems[$V_ITEM_POS]" />
                             <xsl:with-param name="in_amount" select="$lineItems[$V_AMOUNT_POS]" />
                          </xsl:call-template>
                       </xsl:if>
                 </xsl:for-each>
              </LOGIMATIBD00001_subList>
           </LOGIMATIBD00001>
        </LogimatIbdGroup>
     </BODY>
  </DI_TELEGRAM>
</xsl:template>
<!--

 INBOUND DELIVERY LINE TEMPLATE
-->
<xsl:template name="TMPL_INBOUND_DELIVERY_LINE">
  <xsl:param name="in_orderNumber" />
  <xsl:param name="in_sysPartnerLine" />
  <xsl:param name="in_itemNumber" />
  <xsl:param name="in_amount" />
  <LOGIMATIBDL00001>
     <InboundDeliveryLine_InboundDelivery_ibdNo>
        <xsl:value-of select="$in_orderNumber" />
     </InboundDeliveryLine_InboundDelivery_ibdNo>
     <InboundDeliveryLine_sysPartnerLine>
        <xsl:value-of select="$in_sysPartnerLine" />
     </InboundDeliveryLine_sysPartnerLine>
     <InboundDeliveryLine_iga_pkv_Item_itemNo>
        <xsl:value-of select="$in_itemNumber" />
     </InboundDeliveryLine_iga_pkv_Item_itemNo>
     <InboundDeliveryLine_iga_batch></InboundDeliveryLine_iga_batch>
     <InboundDeliveryLine_iga_bbDate></InboundDeliveryLine_iga_bbDate>
     <InboundDeliveryLine_orderAmount_baseQty>
        <xsl:value-of select="$in_amount" />
     </InboundDeliveryLine_orderAmount_baseQty>
  </LOGIMATIBDL00001>
</xsl:template>
<!--

 OUTBOUND DELIVERY TEMPLATE
-->
<xsl:template name="TMPL_OUTBOUND_DELIVERY">
  <xsl:param name="in_lines" />
  <xsl:param name="in_orderNumber" />
  <DI_TELEGRAM>
     <!-- The document root -->
     <HEADER>
        <FULL>
           <HEADER_SOURCE>HOST</HEADER_SOURCE>
           <HEADER_DESTINATION>WAMAS</HEADER_DESTINATION>
           <HEADER_SEQUENCE>1</HEADER_SEQUENCE>
           <HEADER_RECORDTYPENAME>LOGIMATOBD00001</HEADER_RECORDTYPENAME>
        </FULL>
     </HEADER>
     <BODY>
        <!-- The content data -->
        <LogimatObdGroup>
           <LOGIMATOBD00001>
              <OutboundDelivery_obdNo>
                 <xsl:value-of select="$in_orderNumber" />
              </OutboundDelivery_obdNo>
              <OutboundDelivery_priority>
                 <xsl:value-of select="$V_PRIORITY" />
              </OutboundDelivery_priority>
              <OutboundDelivery_deliveryTime></OutboundDelivery_deliveryTime>
              <OutboundDelivery_deliveryNoteNo></OutboundDelivery_deliveryNoteNo>
              <OutboundDelivery_type_obdTypeId>
                 <xsl:value-of select="$V_IBD_TYPE_ID" />
              </OutboundDelivery_type_obdTypeId>
              <OutboundDelivery_externalRef></OutboundDelivery_externalRef>
              <Zone>
                 <xsl:value-of select="$V_ZONE" />
              </Zone>
              <LOGIMATOBD00001_subList>
                 <xsl:for-each select="$in_lines">
                    <xsl:variable name="lineItems" select="tokenize(., ';')" />
                       <!-- remove empty lines -->
                       <xsl:if test="number($lineItems[$V_AMOUNT_POS])">
                          <xsl:call-template name="TMPL_OUTBOUND_DELIVERY_LINE">
                             <xsl:with-param name="in_orderNumber" select="$in_orderNumber" />
                             <xsl:with-param name="in_sysPartnerLine" select="position() -1" />
                             <xsl:with-param name="in_itemNumber" select="$lineItems[$V_ITEM_POS]" />
                             <xsl:with-param name="in_amount" select="number($lineItems[$V_AMOUNT_POS]) * -1" />
                          </xsl:call-template>
                       </xsl:if>
                 </xsl:for-each>
              </LOGIMATOBD00001_subList>
           </LOGIMATOBD00001>
        </LogimatObdGroup>
     </BODY>
  </DI_TELEGRAM>
</xsl:template>
<!--

 OUTBOUND DELIVERY LINE TEMPLATE
-->
<xsl:template name="TMPL_OUTBOUND_DELIVERY_LINE">
  <xsl:param name="in_orderNumber" />
  <xsl:param name="in_sysPartnerLine" />
  <xsl:param name="in_itemNumber" />
  <xsl:param name="in_amount" />
  <LOGIMATOBDL00001>
     <OutboundDeliveryLine_OutboundDelivery_obdNo>
        <xsl:value-of select="$in_orderNumber" />
     </OutboundDeliveryLine_OutboundDelivery_obdNo>
     <OutboundDeliveryLine_sysPartnerLine>
        <xsl:value-of select="$in_sysPartnerLine" />
     </OutboundDeliveryLine_sysPartnerLine>
     <OutboundDeliveryLine_oga_pkv_Item_itemNo>
        <xsl:value-of select="$in_itemNumber" />
     </OutboundDeliveryLine_oga_pkv_Item_itemNo>
     <OutboundDeliveryLine_oga_batch></OutboundDeliveryLine_oga_batch>
     <OutboundDeliveryLine_oga_bbDate></OutboundDeliveryLine_oga_bbDate>
     <OutboundDeliveryLine_orderAmount_baseQty>
        <xsl:value-of select="$in_amount" />
     </OutboundDeliveryLine_orderAmount_baseQty>
  </LOGIMATOBDL00001>
</xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:0)

  

我需要的是将这个数字转换为5.0000甚至更好,   只是5。

如果5,0000包含字符串 translate($testAmount, ',', '.') ,则:

5.0000

将返回substring-before($testAmount, ',') 和:

5

将返回SET @lat=55.866495, @lng=8.168562;

答案 1 :(得分:0)

执行此操作时:

<xsl:variable name="testAmount" select="number($testLineItems[$V_AMOUNT_POS])" />

您正在输入行中获取第二个令牌,并转换为数字。这将给出NaN,因为输入是“5,0000”。在将转换为数字之前,您需要将其转换为字符串“5.0000”

如果声明变量类型,则诊断此类问题通常会容易得多。如果它是一系列字符串,请添加as="xs:string*",如果是双字符则添加as="xs:double",依此类推。它还使您的代码更具可读性和可理解性,并且可以提高性能。