如何在xml元素xslt转换之间添加空格

时间:2016-08-17 07:01:31

标签: xml xslt-1.0 xsl-fo

我有一个XML,如下所示,我使用XSL FO XSLT transforamtion生成PDF。如何在XML元素之间添加空格,同时将它们作为PDF格式的表格列?

<Reports>
<Report>
<BatchDate>2016-08-10T00:00:00</BatchDate>
<ClientAccountNo>ABCDE01384</ClientAccountNo>
<Source>N</Source>
<CDSNo>0000001387</CDSNo>
<Price>0.123000</Price>
<Qty>-1200</Qty>
<TCurrency>USD</TCurrency>
<TNettAmt>0</TNettAmt>
<LCurrency>USD</LCurrency>
<LNettAmt>-86.600000</LNettAmt>
<PromotionInd>N</PromotionInd>
<BrkChgID>BRK-N</BrkChgID>
<BrkChgAmt>50.000000</BrkChgAmt>
<ClrChgID>CLR</ClrChgID>
<ClrChgAmt>10.000000</ClrChgAmt>
<SdcChgID>SDC</SdcChgID>
<SdcChgAmt>1.000000</SdcChgAmt>
<BinChgID />
<BinChgAmt>0</BinChgAmt>
<OthChgAmt>0.000000</OthChgAmt>
<TaxAmt>0.000000</TaxAmt>
</Report>
</Reports>

在输出上述XML时,我需要在XML元素之间添加一个空格,例如,让我们使用TaxAmt,我需要将其输出为Tax Amt。我怎样才能做到这一点?下面是我的XSLT

    <fo:table role="html:table" table-layout="auto" inline-progression-dimension="auto" line-height="2.5" width="100%" border="0px" border-collapse="collapse" border-spacing="3px" border-style="outset hidden" space-before.conditionality="retain" space-after.conditionality="retain" space-after="1em" space-before="1em">
          <!--table header-->
          <xsl:for-each select="//Reports/Report[1]/*">
            <fo:table-column column-width="proportional-column-width(4.77)" font-family="sans-serif" font-size="medium" />
          </xsl:for-each>
          <fo:table-header>

            <fo:table-row height="auto" color="#FFFFFF" background-color="#A1A1A1" text-align="center" font-weight="bold" font-family="sans-serif" font-size="medium">
              <xsl:for-each select="/Reports/Report[1]/*">
                <fo:table-cell text-align="center">
                  <fo:block font-size="medium" font-family="sans-serif">
                    <xsl:value-of select="name()"/>
                  </fo:block>
                </fo:table-cell>
              </xsl:for-each>
            </fo:table-row>
          </fo:table-header>
          <!--table body-->
          <fo:table-body>
            <xsl:for-each select="/Reports/Report">
              <fo:table-row display-align="before">
                <xsl:for-each select="*">
                  <fo:table-cell text-align="center" border-top-color="rgb(255, 255, 255)" border-top-style="solid" border-width="1pt" padding="2pt">
                    <fo:block font-size="medium" font-family="sans-serif">
                      <xsl:text>  </xsl:text> <xsl:value-of select="."/>
                    </fo:block>
                  </fo:table-cell>
                </xsl:for-each>
              </fo:table-row>
            </xsl:for-each>
          </fo:table-body>
        </fo:table>

1 个答案:

答案 0 :(得分:0)

以下模板调用在大写字符之前插入空格。 XSL格式化引擎将忽略第一次出现的空间。

<!--xsl:value-of select="name()"/-->
<xsl:call-template name="insertSpaceBeforeUCase">
    <xsl:with-param name="prmStr" select="name()"/>
</xsl:call-template>

...
<xsl:template name="insertSpaceBeforeUCase">
    <xsl:param name="prmStr" select="''"/>
    <xsl:variable name="firstChar" select="substring($prmStr,1,1)"/>
    <xsl:if test="translate($firstChar,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','')=''">
        <xsl:text>&#x20;</xsl:text>
    </xsl:if>
    <xsl:value-of select="$firstChar"/>
    <xsl:if test="string-length($prmStr) &gt; 1">
        <xsl:call-template name="insertSpaceBeforeUCase">
            <xsl:with-param name="prmStr" select="substring($prmStr,2)"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

通过此模板调用“TaxAmt”将转换为“Tax Amt”。但是“ClrChgID”被转换为“Sdc Chg I D”。后者可能不是你想要的。

XSLT 1.0对字符串处理有限制。如果您可以将样式表移动到XSLT 2.0,则此问题还有另一种解决方案。

[附录]

位精制版本在这里:

<xsl:template name="insertSpaceBeforeUCase">
    <xsl:param name="prmStr" select="''"/>
    <xsl:param name="prmPrevChar" select="''"/>
    <xsl:variable name="firstChar" select="substring($prmStr,1,1)"/>
    <xsl:variable name="nextChar" select="substring($prmStr,2,1)"/>
    <xsl:if test="(translate($firstChar,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','') = '')
        and ($prmPrevChar != '')
        and ((translate($prmPrevChar,'abcdefghijklmnopqrstuvwxyz','') = '') or ($nextChar != '') and (translate($nextChar,'abcdefghijklmnopqrstuvwxyz','') = ''))">
        <xsl:text>&#x20;</xsl:text>
    </xsl:if>
    <xsl:value-of select="$firstChar"/>
    <xsl:if test="string-length($prmStr) &gt; 1">
        <xsl:call-template name="insertSpaceBeforeUCase">
            <xsl:with-param name="prmStr" select="substring($prmStr,2)"/>
            <xsl:with-param name="prmPrevChar" select="$firstChar"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

此模板生成以下XSL-FO:

  <fo:table-row height="auto" color="#FFFFFF" background-color="#A1A1A1" text-align="center" font-weight="bold" font-family="sans-serif" font-size="medium">
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Batch Date</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Client Account No</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Source</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">CDS No</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Price</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Qty</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">T Currency</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">T Nett Amt</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">L Currency</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">L Nett Amt</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Promotion Ind</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Brk Chg ID</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Brk Chg Amt</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Clr Chg ID</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Clr Chg Amt</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Sdc Chg ID</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Sdc Chg Amt</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Bin Chg ID</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Bin Chg Amt</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Oth Chg Amt</fo:block>
     </fo:table-cell>
     <fo:table-cell text-align="center">
        <fo:block font-size="medium" font-family="sans-serif">Tax Amt</fo:block>
     </fo:table-cell>
  </fo:table-row>