2016-09-22 191 views
0

我有一個用於將CSV轉換爲XML的XSLT。 csv的第二列包含數字,例如,5,0000用XSL中的點替換逗號

我需要的是將此數字轉換爲5.0000或甚至更好,只是5.意思是:將a替換爲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> 
+0

您是否嘗試過使用''和'format-number(123.456,xyz,'random' )'? – uL1

+0

考慮將示例最小化爲僅顯示問題所需的內容 - 請參閱:[mcve]。 –

+0

不要告訴我們你有錯誤。告訴我們錯誤是什麼。你可能不瞭解它,但我們可能會這麼做。 –

回答

0

我需要的是這個數字變成5.0000,甚至更好, 僅有5。

如果$testAmount包含5,0000,則:

translate($testAmount, ',', '.') 

將返回5.0000和:

substring-before($testAmount, ',') 

將返回5

0

當你這樣做:

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

你正在你的輸入行的第二個令牌,並轉換爲數字。這會給NaN,因爲輸入是「5,0000」。您需要將其轉換爲字符串「5.0000」之後將其轉換爲數字。

如果您聲明變量的類型,診斷這類問題通常要容易得多。如果它是一串字符串,則加上as="xs:string*",如果是雙精度則加上as="xs:double",依此類推。它還使您的代碼更具可讀性和可理解性,並且可以提高性能。