Monday 22 November 2021

xslt padding with characters call template for left pad and right pad

 

Could a call-template be written that took two parameters ?

 

a string, and a  number) return the string with empty spaces appended to the 

end so that it  occupied the number of spaces specified by the number  parameter? 

   

So long as you know the number of spaces will never exceed say 100, write

<xsl:template name="pad">

<xsl:param name="s"/>

<xsl:param name="len"/>

<xsl:variable name="spaces">         ...                   </xsl:variable>

<xsl:value-of select="substring(concat($s, $spaces), 1, $len)"/>

</xsl:template>

 

A more elegant solution, which handles any number of spaces, is

for the template to append

one space to the string and then call itself to add another "len-1", until len reaches zero.

You should check out XPath's string-handling functions.

Something like

<xsl:value-of

     select="substring(concat($string, '            '), 1, 12))"/>

Always gives you a string twelve characters long, either the first twelve

characters of $string, or $string padded out with spaces. Variables can be also be

 useful to make things easier to read, reuse and maintain -- for example

<xsl:variable name="spacex12" select="'            '"/>

and then

<xsl:value-of select="substring(concat($string, $spacex12), 1, 12))"/>

 

Example

Just as a challenge, I took it a little further. The following outputs the

color values in this document

  <test>

  <color>red</color>

  <color>blue</color>

  <color>yellow</color>

  </test>

at 12 characters each, right aligned:

  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 

  version="1.0">

    <xsl:variable name="fieldWidth">12</xsl:variable>

 

    <xsl:template match="color">

      <xsl:variable name="valueLength"

           select="string-length(normalize-space(.))"/>

      <xsl:variable name="padding"

           select="$fieldWidth - $valueLength"/>

 

      <xsl:text>[</xsl:text>

      <xsl:value-of select="substring('                  ',1,$padding)"/>

      <xsl:value-of select="."/>

      <xsl:text>]</xsl:text>

    </xsl:template>

 

  </xsl:stylesheet>

giving this output:

  <?xml version="1.0" encoding="utf-8"?>

  [         red]

  [        blue]

  [      yellow]

for Fixed-length String Output

Here are the string padding functions that I use frequently:

 

 

 

  <xsl:template name="prepend-pad">   

  <!-- recursive template to right justify and prepend-->

  <!-- the value with whatever padChar is passed in   -->

    <xsl:param name="padChar"> </xsl:param>

    <xsl:param name="padVar"/>

    <xsl:param name="length"/>

    <xsl:choose>

      <xsl:when test="string-length($padVar) &lt; $length">

        <xsl:call-template name="prepend-pad">

          <xsl:with-param name="padChar" select="$padChar"/>

          <xsl:with-param name="padVar" select="concat($padChar,$padVar)"/>

          <xsl:with-param name="length" select="$length"/>

        </xsl:call-template>

      </xsl:when>

      <xsl:otherwise>

        <xsl:value-of select="substring($padVar,string-length($padVar) -

$length + 1)"/>

      </xsl:otherwise>

    </xsl:choose>

  </xsl:template>

 

 

  <xsl:template name="append-pad">   

  <!-- recursive template to left justify and append  -->

  <!-- the value with whatever padChar is passed in   -->

    <xsl:param name="padChar"> </xsl:param>

    <xsl:param name="padVar"/>

    <xsl:param name="length"/>

    <xsl:choose>

      <xsl:when test="string-length($padVar) &lt; $length">

        <xsl:call-template name="append-pad">

          <xsl:with-param name="padChar" select="$padChar"/>

          <xsl:with-param name="padVar" select="concat($padVar,$padChar)"/>

          <xsl:with-param name="length" select="$length"/>

        </xsl:call-template>

      </xsl:when>

      <xsl:otherwise>

        <xsl:value-of select="substring($padVar,1,$length)"/>

      </xsl:otherwise>

    </xsl:choose>

  </xsl:template>

 

 

Eg: to call the template from xsl variable or element

 

<ns39:elementname>

                                      <xsl:call-template name="prepend-padzero">

                                            <xsl:with-param name="padChar" select="0"/>

                                            <xsl:with-param name="padVar" select="nsmpr5:InvoiceNumber"/>

                                            <xsl:with-param name="length" select="6"/>

                                      </xsl:call-template>

                                      <!--  <xsl:value-of xml:id="id_754" select="concat (&quot;AUT&quot;,nsmpr5:InvoiceNumber)"/> -->

                                </ns39: elementname >

 

 

 

 

 

These will both ensure that the string ends up to be whatever length you pass

in (ie. if the string is longer than expected it will also truncate).

Pete Forman adds an option for left padding

Here's an example of padding on the left using a similar technique.

It prints my size attribute to a width of 4.

<xsl:value-of select="substring(concat('    ', @size),

                       string-length(@size) + 1, 4)"/>

 

This is clearly not as versatile as some of the solutions but it suffices for simple cases.

 

How to pad space to a text node to make it have specific length

 

These are the templates I use to pad on the left or right with any character passed in:

  <xsl:template name="prepend-pad">   

  <!-- recursive template to right justify and prepend-->

  <!-- the value with whatever padChar is passed in   -->

    <xsl:param name="padChar"> </xsl:param>

    <xsl:param name="padVar"/>

    <xsl:param name="length"/>

    <xsl:choose>

      <xsl:when test="string-length($padVar) &lt; $length">

        <xsl:call-template name="prepend-pad">

          <xsl:with-param name="padChar" select="$padChar"/>

          <xsl:with-param name="padVar" select="concat($padChar,$padVar)"/>

          <xsl:with-param name="length" select="$length"/>

        </xsl:call-template>

      </xsl:when>

      <xsl:otherwise>

        <xsl:value-of

                 select="substring($padVar,string-length($padVar) -

                 $length + 1)"/>

      </xsl:otherwise>

    </xsl:choose>

  </xsl:template>

 

  <xsl:template name="append-pad">   

  <!-- recursive template to left justify and append  -->

  <!-- the value with whatever padChar is passed in   -->

    <xsl:param name="padChar"> </xsl:param>

    <xsl:param name="padVar"/>

    <xsl:param name="length"/>

    <xsl:choose>

      <xsl:when test="string-length($padVar) &lt; $length">

        <xsl:call-template name="append-pad">

          <xsl:with-param name="padChar" select="$padChar"/>

          <xsl:with-param name="padVar" select="concat($padVar,$padChar)"/>

          <xsl:with-param name="length" select="$length"/>

        </xsl:call-template>

      </xsl:when>

      <xsl:otherwise>

        <xsl:value-of select="substring($padVar,1,$length)"/>

      </xsl:otherwise>

    </xsl:choose>

  </xsl:template>

The 'padChar' param passed in could be as many characters as you want, actually. 'padVar'

is the variable to pad, and length is length,

obviously. Most of the XSLT I do is for fixed-length text files, and these haven't failed me yet.

Sunday 24 October 2021

B2B OIC Outbound Batching

                                                               

As OIC gen 2 does not have a provision of batching outbound EDI batching, below is the workaround steps to achieve it.

 

1.       Create ISA Headers and stage it in a file

 

Translate 810 invoice with b2b translator!

 

    

 

normalize-space(substring-before($readheader/nsmpr15:ReadResponse/nsmpr1:tes/nsmpr1:test/nsmpr1:C1,"ST*810"))

 

The above string will give you the ISA segment before ST segment.

 

2.               Next ST-segment loop

 




 

Loop the multiple invoices to get the ST repeating segments, I have used the Translate EDI activity.



 

For writing the ST segment  file I used the below schema and appended to the same ISA file , so that we will have ISA and then ST repeating segments.

 

<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

            xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd"

            xmlns:tns="http://TargetNamespace.com/fileReference/writedi"

            targetNamespace="http://TargetNamespace.com/fileReference/writedi"

            elementFormDefault="qualified"

            attributeFormDefault="unqualified"

            nxsd:version="NXSD"

            nxsd:stream="chars"

            nxsd:encoding="UTF8"

> 

 

 

  <xsd:element name="tes">

    <xsd:complexType>

      <xsd:sequence>         

        <xsd:element ref="tns:test" minOccurs="1" maxOccurs="unbounded" />

      </xsd:sequence>

    </xsd:complexType>

  </xsd:element>

  <xsd:element name="test" type="tns:testType" />

  <xsd:complexType name="testType">

    <xsd:sequence>

      <xsd:element name="C1" type="xsd:string"  nxsd:style="terminated" nxsd:terminatedBy="${eof}" nxsd:quotedBy="&quot;" />

    </xsd:sequence>

  </xsd:complexType>

</xsd:schema>

 

3.       Footer Segment (GE and IE)






 

<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

            xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd"

            xmlns:tns="http://TargetNamespace.com/fileReference/writedi"

            targetNamespace="http://TargetNamespace.com/fileReference/writedi"

            elementFormDefault="qualified"

            attributeFormDefault="unqualified"

            nxsd:version="NXSD"

            nxsd:stream="chars"

            nxsd:encoding="UTF8"

> 

 

 

  <xsd:element name="Edi810">

    <xsd:complexType>

      <xsd:sequence>

        <xsd:element ref="tns:Edi_810" minOccurs="1" maxOccurs="unbounded" />

      </xsd:sequence>

    </xsd:complexType>

  </xsd:element>

  <xsd:element name="Edi_810" type="tns:Edi810Type" />

  <xsd:complexType name="Edi810Type">

    <xsd:sequence>

      <xsd:element name="Record" type="xsd:string"  nxsd:style="terminated" nxsd:terminatedBy="${eol}"  />

    </xsd:sequence>

  </xsd:complexType>

</xsd:schema>

 

Run the Integration and you will see the EDI outbound batching into single edi file .


Happy Learning 

 

====================================================================================

 

xslt padding with characters call template for left pad and right pad

  Could a call-template be written that took two parameters ?   a string, and a   number) return the string with empty spaces appended t...