这只是信息共享。我已经知道解决方案了:)我很难做到!我在这里想要两件事:
- 分享我到目前为止所达到的。
- 想知道是否有人有更好的解决方案
没有源 XML 就很难判断。但是我曾经有一个需求并使用了递归模板。
我的输入 XML 是:
<?xml version="1.0" encoding="UTF-8"?>
<Order>
<Item>
<RECORD_ID>RECORD_ID</RECORD_ID>
<ENTITY_CODE>ENTITY_CODE</ENTITY_CODE>
<USER_CODE>USER_CODE</USER_CODE>
<RECORD_DATE>RECORD_DATE</RECORD_DATE>
<ITEM_CODE>ITEM_CODE</ITEM_CODE>
<LINE_QUANTITY>LINE_QUANTITY</LINE_QUANTITY>
<LINE_PRICE>LINE_PRICE</LINE_PRICE>
<LINE_DISCOUNT_PERCENT>LINE_DISCOUNT PERCENT</LINE_DISCOUNT_PERCENT>
<HEADER_SPECIAL_INSTRUCTIONS>HEADER_SPECIAL_INSTRUCTIONS</HEADER_SPECIAL_INSTRUCTIONS>
</Item>
<Item>
<RECORD_ID>1850</RECORD_ID>
<ENTITY_CODE>I65647</ENTITY_CODE>
<USER_CODE>135</USER_CODE>
<RECORD_DATE>2011-05-27</RECORD_DATE>
<ITEM_CODE>798159</ITEM_CODE>
<LINE_QUANTITY>1</LINE_QUANTITY>
<HEADER_SPECIAL_INSTRUCTIONS>HEADER_SPECIAL_INSTRUCTIONS HEADER_SPECIAL_INSTRUCTIONS HEADER_SPECIAL_INSTRUCTIONS HEADER_SPECIAL_INSTRUCTIONS</HEADER_SPECIAL_INSTRUCTIONS>
</Item>
</Order>
我不得不拆分特殊说明文本,但仅限于<Item>
元素 > 1。所以我想出了这个模板:
<xsl:template name="Texts">
<xsl:param name="string" select="Item[2]/HEADER_SPECIAL_INSTRUCTIONS" />
<xsl:param name="line-length" select="70"/>
<xsl:variable name="line" select="substring($string,1,$line-length)"/>
<xsl:variable name="rest" select="substring($string, $line-length+1)"/>
<xsl:if test="$line">
<E1EDKT2 SEGMENT="1">
<TDLINE>
<xsl:value-of select="$line"/>
</TDLINE>
<TDFORMAT>*</TDFORMAT>
</E1EDKT2>
</xsl:if>
<xsl:if test="$rest">
<xsl:call-template name="Texts">
<xsl:with-param name="string" select="$rest"/>
<xsl:with-param name="line-length" select="$line-length"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
该模板的 XML 输出为:
<?xml version="1.0" encoding="UTF-8"?>
<E1EDKT1 SEGMENT="1">
<TDID>ZA01</TDID>
<E1EDKT2 SEGMENT="1">
<TDLINE>HEADER_SPECIAL_INSTRUCTIONS HEADER_SPECIAL_INSTRUCTIONS
HEADER_SPECIAL</TDLINE>
<TDFORMAT>*</TDFORMAT>
</E1EDKT2>
<E1EDKT2 SEGMENT="1">
<TDLINE>_INSTRUCTIONS HEADER_SPECIAL_INSTRUCTIONS</TDLINE>
<TDFORMAT>*</TDFORMAT>
</E1EDKT2>
</E1EDKT1>
由于我不知道您的源 XML - 您应该始终提供(至少是一个小的代表性版本) - 我无法以任何方式修复您的 XSLT。但请尝试根据您的需要调整我的模板。
<xsl:template name="break-to-length">
<xsl:param name="text" />
<xsl:param name="length" />
<xsl:variable name="first-half" select="substring($text,0,$length)" />
<xsl:variable name="second-half" select="substring-after($text, $first-half)" />
<xsl:variable name="last-five-chars-of-first-half" select="substring-after($first-half,substring($first-half, 0, $length - 5))" />
<xsl:variable name="alternative-first-half">
<xsl:choose>
<xsl:when test="contains($last-five-chars-of-first-half, $space)">
<xsl:value-of select="concat(substring($first-half, 0, $length - 5), substring-before($last-five-chars-of-first-half, $space))" />
</xsl:when>
<xsl:when test="contains($last-five-chars-of-first-half, $dot)">
<xsl:value-of select="concat(substring($first-half, 0, $length - 5), substring-before($last-five-chars-of-first-half, $dot), $dot)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$first-half" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="alternative-second-half">
<xsl:choose>
<xsl:when test="contains($last-five-chars-of-first-half, $space)">
<xsl:value-of select="concat(substring-after($last-five-chars-of-first-half, $space), $second-half)" />
</xsl:when>
<xsl:when test="contains($last-five-chars-of-first-half, $dot)">
<xsl:value-of select="concat(substring-after($last-five-chars-of-first-half, $dot), $second-half)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$second-half" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- if first half doesn't end with a space or dot -->
<xsl:variable name="word-was-cut" select="$alternative-first-half = $first-half" />
<xsl:value-of select="$alternative-first-half" />
<xsl:choose>
<xsl:when test="string-length($alternative-second-half) = 0">
<!-- Do Nothing -->
</xsl:when>
<xsl:when test="string-length($alternative-second-half) < $length">
<!-- if first half doesn't end with a space or dot -->
<xsl:if test="$word-was-cut">
<xsl:text>-</xsl:text>
</xsl:if>
<fo:block />
<xsl:value-of select="$alternative-second-half" />
</xsl:when>
<xsl:otherwise>
<!-- Second half is longer than max length -->
<!-- if first half doesn't end with a space -->
<xsl:if test="$word-was-cut">
<xsl:text>-</xsl:text>
</xsl:if>
<fo:block />
<xsl:call-template name="break-to-length">
<xsl:with-param name="text" select="$alternative-second-half"/>
<xsl:with-param name="length" select="$length" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>