动态换行 - 基于XSLT 1和2的条件

时间:2013-07-14 09:37:50

标签: xslt-2.0

我的输出类型是text。 我正准备报道。 我的文本输出后只能接受50个字符宽度,必须包含在下一行。 我有一个解决方案来换行文本中的元素。 有没有办法包装整个报告而不是为每一行做? 我可以为整个文件做吗? 我有线包裹的解决方案,我的问题是我有很多条件如下:

  

名字姓氏路由(condition1)(条件2)(条件3)   (条件4)..继续......

让我们假设:

名字fixedwidth是15, lastname固定宽度为15,城市固定宽度为3 ...

之后,条件1将有10个宽度,条件2有15个固定然后继续......

重要的是,这些条件只是选项......

所以15 + emptyspace + 15 + emptyspace + 3 = 36我的情况将从第36列开始..

在第一次换行之后,我将继续从同一条线继续即将到来的条件。 因此,对于下一个项目,我找到了开始和结束位置。 如何解决这个问题?

xml输入:

    <?xml version="1.0" encoding="UTF-8"?>
    <passengerlist>
      <passengers>
        <Firstname>JOHNNNNNNNNNNNN</Firstname>
        <lastname>MARKKKKKKKKKKKK</lastname>
        <comments>abcdefh abc abcde abc dekf jl</comments>
         <route>air</route>
      </passengers>
    <!-- <passengers>
      <Firstname>ANTONYYYYYYYYYYY</Firstname>
      <lastname>NORMAN</lastname>
      <comments>abcdefddddddddghhhhhhhhhhhhhh</comments>
      <route>air</route>
    </passengers>
    <passengers>
      <Firstname>BRITTOOOOOOOOOO</Firstname>
      <lastname>MARKKKKKKK</lastname>
      <comments>abcdedfffghghghghghghghghghghghghgh</comments>
      <route>cruise</route>
     </passengers> -->
   </passengerlist>

XSLT代码:                         

  <!-- For line Wrapping -->

  <xsl:template name="callEmpty">
    <xsl:param name="callEmpty"/>
    <xsl:variable name="LNemptyCheck" select="$callEmpty"></xsl:variable>
  </xsl:template> 

  <xsl:template name="text_wrapper">
    <xsl:param name="Text"/>
    <xsl:choose>
      <xsl:when test="string-length($Text)">
        <xsl:value-of select="substring($Text,1,15)"/>
        <xsl:if test="string-length($Text) &gt; 15">
          <xsl:value-of select="$newline"/>
        </xsl:if>
        <xsl:call-template name="wrapper_helper">
          <xsl:with-param name="Text" select="substring($Text,16)"/>   
        </xsl:call-template>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

 <xsl:template name="wrapper_helper">
  <xsl:param name="Text"/>
  <xsl:value-of select="substring($Text,1,15)"/>
  <xsl:text>&#xa;</xsl:text>
  <xsl:call-template name="text_wrapper">
    <xsl:with-param name="Text" select="substring($Text,15)"/>
  </xsl:call-template>
 </xsl:template> 

 <!-- Template for Line wrapping --> 

 <xsl:template match="/">

 <xsl:for-each select="passengerlist/passengers">

   <xsl:value-of select="Firstname"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="lastname"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="route"/>
   <xsl:text> </xsl:text>
   <xsl:variable name="firstwrap">
     <xsl:if test="route='air'">

       <xsl:value-of select="Firstname"/>
       <xsl:text> </xsl:text>
       <xsl:value-of select="comments"/>
     </xsl:if>
   </xsl:variable>
   <xsl:call-template name="text_wrapper">
      <xsl:with-param name="Text" select="$firstwrap"/>
   </xsl:call-template>

输出:

  

JOHNNNNNNNNNNNN MARKKKKKKKKKKKK空气公司JOHNNNNNNNNNNNN    abcdefh abc ab   bcde abc dekf jl    MARKKKKKKKKKKK abcdefh abc ab bcde abc dekf jl

期待:

  

JOHNNNNNNNNNNNN MARKKKKKKKKKKKK空气公司JOHNNNNNNNNNNNN abcdefh abc ab   bcde abc dekf jl MARKKKKKKKKKKKK abcdefh abc abbcde abc dekf jl

请帮我解决一下我的问题,或者告诉我在XSLT中有可能吗?

1 个答案:

答案 0 :(得分:1)

我不确定你的问题到底是什么(我看不出你得到的输出和你预期的输出之间有什么显着差异)。但我认为有可能使它更简单。我准备了一些测试输入xml(只是非常简单的演示)。

<?xml version="1.0" encoding="UTF-8"?>
<Input>
    <Line>Some long text is on the first line.</Line>
    <Line>Some longer text is on the second line.</Line>
    <Line>But the longest text occures on the third line.</Line>
</Input>

在下面的xslt中,我存储每行的处理结果(即其文本的副本,并根据某些条件附加其他文本)到变量中。然后我使用用户函数立即包装此变量(也可以使用命名模板完成)。

<?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="http://www.w3.org/2005/xpath-functions" xmlns:my="my-ns">
    <xsl:output method="text" />

    <xsl:variable name="newLineCharacter" select="'&#10;'" />
    <xsl:variable name="maxLineWidth" select="50" />

    <xsl:template match="/">
        <xsl:apply-templates select="Input/Line" />
    </xsl:template>

    <xsl:template match="Line">
        <!-- Process the line and store the result into variable-->
        <xsl:variable name="processedText">
            <xsl:value-of select="." />
            <xsl:text> </xsl:text>
            <xsl:if test="position() &gt;= 1">
                <xsl:text>First condition is true. </xsl:text>
            </xsl:if>
            <xsl:if test="position() &gt;= 2">
                <xsl:text>Second condition is true. </xsl:text>
            </xsl:if>
            <xsl:if test="position() &gt;= 3">
                <xsl:text>Third condition is true. </xsl:text>
            </xsl:if>                   
            <!-- et cetera, et cetera ...-->
        </xsl:variable>
        <!-- Wrap the text stored in a variable -->
        <xsl:value-of select="my:wrapText($processedText, $maxLineWidth)" />
    </xsl:template>

    <xsl:function name="my:wrapText">
        <xsl:param name="textToBeWrapped" />
        <xsl:param name="maximumWidth" />

        <xsl:value-of select="substring($textToBeWrapped,1,$maximumWidth)" />
        <xsl:value-of select="$newLineCharacter" />

        <xsl:if test="string-length($textToBeWrapped) &gt; $maximumWidth">
            <!-- Recursive call of my:wrapText to wrap the rest of the text -->
            <xsl:value-of select="my:wrapText(substring($textToBeWrapped,$maximumWidth+1), $maximumWidth)" />
            </xsl:if>
    </xsl:function>

</xsl:stylesheet>

输出

Some long text is on the first line. First conditi
on is true. 
Some longer text is on the second line. First cond
ition is true. Second condition is true. 
But the longest text occures on the third line. Fi
rst condition is true. Second condition is true. T
hird condition is true. 

我希望它能满足您的需求。