映射复杂类型和字段大小

时间:2011-12-02 02:40:46

标签: xslt

我有一个xml文档,我需要使用以下条件将源xml文档中的描述字段映射到目标xml文档:

源XML文档说明字段可以有一个可变长度0 - 1000个字符。

目标字段具有复杂类型的PID元素(xml中的Invoice EDI)。 PID的每个实例必须在PID01中具有字符“F”,并且在PID05字段中具有40个字符。我们需要生成足够的PID元素以适应字段描述的完整值。每个PID05应该存储40个字符,除了最后一个PID实例,它将具有提醒符号,因此它可以更短。

XML Messages http://i41.tinypic.com/6roosl.png

有人可以建议我如何在xslt中执行此操作吗?

我假设我们需要计算描述字段的大小,然后将其除以40以获得我们需要在目标xml消息上创建的PID元素的数量,然后一次复制每个40个字符的段放置' PID01中的F'和PID05中的40个字符?

非常感谢...

干杯

示例输出为:

<PID>
  <PID01>F</PID01>
  <PID05>The quick </PID05>
</PID>
<PID>
  <PID01>F</PID01>
  <PID05>brown fox </PID05>
</PID>
<PID>
  <PID01>F</PID01>
  <PID05>jumped over</PID05>
</PID>

1 个答案:

答案 0 :(得分:1)

我不确定您的确切要求,但您可以使用递归模板将输入文本拆分为 PID05 元素,每个元素包含40个字符。

例如,考虑这个元素

<text>The quick brown fox jumps over the lazy dog</text>

然后,使用以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes" />

   <xsl:param name="splitLength" select="10"/>

   <!-- Pad out a string with excess characters -->
   <xsl:template name="pad">
      <xsl:param name="padChar" />
      <xsl:param name="count" select="$splitLength" />
      <xsl:value-of select="$padChar" />
      <xsl:if test="$count &gt; 1">
         <xsl:call-template name="pad">
            <xsl:with-param name="padChar" select="$padChar" />
            <xsl:with-param name="count" select="$count - 1" />
         </xsl:call-template>
      </xsl:if>
   </xsl:template>

   <xsl:template match="/text">
      <xsl:call-template name="splitter">
         <xsl:with-param name="text" select="text()"/>
      </xsl:call-template>
   </xsl:template>

   <xsl:template name="splitter">
      <xsl:param name="text"/>
      <PID>
         <PID01>F</PID01>
         <PID05>
            <xsl:value-of select="substring($text, 1, $splitLength)"/>
            <xsl:if test="string-length($text) &lt; $splitLength">
               <xsl:call-template name="pad">
                  <xsl:with-param name="padChar" select="' '" />
                  <xsl:with-param name="count" select="$splitLength - string-length($text)" />
               </xsl:call-template>
            </xsl:if>
         </PID05>
      </PID>
      <xsl:if test="string-length($text) &gt; $splitLength">
         <xsl:call-template name="splitter">
            <xsl:with-param name="text" select="substring($text, $splitLength + 1, string-length($text))"/>
         </xsl:call-template>
      </xsl:if>
   </xsl:template>
</xsl:stylesheet>

然后输出以下内容

<PID>
   <PID01>F</PID01>
   <PID05>The quick </PID05>
</PID>
<PID>
   <PID01>F</PID01>
   <PID05>brown fox </PID05>
</PID>
<PID>
   <PID01>F</PID01>
   <PID05>jumps over</PID05>
</PID>
<PID>
   <PID01>F</PID01>
   <PID05> the lazy </PID05>
</PID>
<PID>
   <PID01>F</PID01>
   <PID05>dog       </PID05>
</PID>

注意我在这里参数化了分割长度,并将其设置为10,而不是40,仅作为示例。

那里不存在命名模板,它将最后一个PID05元素填充为精确长度(在这种情况下为10)。