XML Data transform

  • 1 November 2016
  • 6 replies
  • 4 views

Badge +1

Hello!

I have a question about data transform.

I have a chain of processes. I need to insert to the flexi task notification a variable that contains information about all updates in table style.

 

I read information about the item by “Call Web service” action.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://schemas.microsoft.com/sharepoint/soap/">
  <soap:Header>
  </soap:Header>
  <soap:Body>
    <m:GetVersionCollection>
      <m:strlistID>{Common:ListID}</m:strlistID>
      <m:strlistItemID>{ItemProperty:ID}</m:strlistItemID>
      <m:strFieldName>AppendedText</m:strFieldName>
    </m:GetVersionCollection>
  </soap:Body>
</soap:Envelope>

This action provide me XML:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <soap:Body>

    <GetVersionCollectionResponse xmlns="http://schemas.microsoft.com/sharepoint/soap/">

      <GetVersionCollectionResult>

        <Versions>

          <Version Comment="User, First (Approve) 10/28/2016 3:14 PM - 10/28/2016 3:14 PM&#xA;(User, First) Some text comment" Modified="2016-10-28T12:14:37Z" Editor="2;#User,, First,#i:0#.w|domainfirst,#first.user@domain.com,#first.user@domain.com,#First,, User" />

          <Version Comment="User, Second (Approve) 10/28/2016 3:13 PM - 10/28/2016 3:13 PM&#xA;(User, Second ) One more text comment" Modified="2016-10-28T12:13:59Z" Editor="2;#User,, Second ,#i:0#.w|domainsecond,#Second.user@domain.com,#Second.user@domain.com,#User,, Second" />

          </Versions>

      </GetVersionCollectionResult>

    </GetVersionCollectionResponse>

  </soap:Body>

</soap:Envelope>

 

I’m trying to transform this data using XSL or XPath transform in to the table like below and insert it to the task notification:

table example

I used the link to Vadim Tabakman site (http://www.vadimtabakman.com/nintex-workflow-xsl-transformation.aspx) and tried to do as he describes, but without success.

 

Could you please help or advice me  if it possible, with XSL transform.


6 replies

Userlevel 5
Badge +14

since your data are not 'sufficiently' structured, it's quite a problem to parse out substrings out of the single attributes.

I came up with following XSLT transformation.

note however, it might be sensitive on appearance of delimiters within attributes values.

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

  <xsl:template match="/">

    <html>
      <body>
        <h2>Table</h2>
        <table border="1">
          <tr bgcolor="blue">
            <th>User</th>
            <th>Date</th>
            <th>Comment</th>
          </tr>
          <xsl:for-each select="//*[name()='Version']">
            <tr>
              <td>
                <xsl:call-template name="tokenizeString">
                  <xsl:with-param name="list" select="@Editor"/>
                  <xsl:with-param name="delimiter" select="',#'"/>
                  <xsl:with-param name="index" select="'5'"/>
                </xsl:call-template>
              </td>
              <td>
                <xsl:value-of select="@Modified"/>
              </td>
              <td>
                <xsl:variable name="CommentText" >
                  <xsl:call-template name="tokenizeString">
                    <xsl:with-param name="list" select="@Comment"/>
                    <xsl:with-param name="delimiter" select="'&#xA;'"/>
                    <xsl:with-param name="index" select="'2'"/>
                  </xsl:call-template>
                </xsl:variable>
                <xsl:value-of select="substring-after($CommentText,') ')"/>
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>

  </xsl:template>


  <xsl:template name="tokenizeString">
    <xsl:param name="list"/>
    <xsl:param name="delimiter"/>
    <xsl:param name="index"/>
    <xsl:param name="locIdx" select="'1'" ></xsl:param>
    <xsl:choose>
      <xsl:when test="contains($list, $delimiter)">
          <xsl:if test="$index = $locIdx">
            <xsl:value-of select="substring-before($list,$delimiter)"/>
          </xsl:if>
          <xsl:call-template name="tokenizeString">
            <xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
            <xsl:with-param name="delimiter" select="$delimiter"/>
            <xsl:with-param name="index" select="$index"/>
            <xsl:with-param name="locIdx" select="$locIdx+1"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:choose>
            <xsl:when test="$list = ''">
              <xsl:text/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:if test="$index = $locIdx">
                <xsl:value-of select="$list"/>
              </xsl:if>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

  </xsl:stylesheet>

Badge +1

Thanks for reply, I will try.

Userlevel 5
Badge +14

Hi Oleg Chuev‌,

were you able to test provided solution?

if so, and it helped you, could you close the thread by marking question answered?

Badge +1

Hello Marian,

Problem was solved other way

Userlevel 5
Badge +14

would you mind to share your solution?

it might help other users that come accross the same issue.

thanks.

Badge +1

I declined the idea of collecting text comments, now I using the web part of the workflow tasks with filtering on the form of the element. This is not the best way, but much simpler.

Reply