XSLT

Questions about XML that are not covered by the other forums should go here.
Daniel Kakona
Posts: 6
Joined: Thu Apr 19, 2018 10:07 am

XSLT

Post by Daniel Kakona »

Hi all,

I have a ticketing system which receives emails formatted in xml sent by users. The system uses an xslt script to convert the xml formatted email into the supported xml format that the system uses to create a ticket.

Below is an example of the email format which is sent to the system:

<INCIDENT>
<DESCRIPTION>
First Name: Paul
Last Name: Luis
Email Address: paul.l@yahoo.com
Contact Number: 0123456789
How can we help you: Testing </DESCRIPTION>
</INCIDENT>

The content found between the tag Description is copied into the description of the ticket is below:

First Name: Paul
Last Name: Bonthuys
Email Address: paul.b@yahoo.com
Contact Number: 0123456789
How can we help you: Testing

The issue I am having is that all the text after the email address is cut and not displayed in the ticket description field. So the description field only shows as below:

First Name: Paul
Last Name: Bonthuys
Email Address: paul.b@yahoo.com

Of course I have the option of moving the email address to the end of the Description tag, but I will like to keep the sequence of how the information is displayed i.e. First Name, Last Name, Email Address, Contact Number. I am suspecting that the email address hyperlink is causing the text after it to be cut and not being displayed.

Below is a sample of my xslt script which copies the content of my email into the ticket description field:


<xsl:when test="name() = 'Body'">
<xsl:variable name="emailbody">
<xsl:choose>
<xsl:when test="starts-with(normalize-space(.), '<INCIDENT>')">
<xsl:call-template name="StringToXML">
<!-- remove CRLF -->
<xsl:with-param name="text" select="translate(., '&#xA;', '')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Email body does not contain XML for Incident'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="parameters" select="msxsl:node-set($emailbody)/tag[@name='INCIDENT']/tag"/>
<xsl:variable name="symptom" select="$parameters[@name='DESCRIPTION']/text()"/>

<!-- Symptom -->
<xsl:element name="Field">
<xsl:attribute name="Name">
<xsl:text>Symptom</xsl:text>
</xsl:attribute>
<xsl:choose>
<xsl:when test="string-length($symptom) > 0">
<xsl:value-of select="$symptom"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>Default Symptom goes here</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:element>


</xsl:when>

Anyone has an idea of how I could strip the hyperlink in the email address so that some texts are not cut?

XSLT CODE
<?xml version="1.0" encoding="UTF-8"?>
<!--
This XSLT sample will convert the following email body in XML format generated by the Email Service to hierarchical XML that can be consumed by the Integration Server using SchemaVersion "1.0".
<INCIDENT>
<DESCRIPTION>PC is very slow</DESCRIPTION>
<SERVICE>Desktop Service</SERVICE>
<CATEGORY>Performance Issue</CATEGORY>
<OWNER>Quality Assurance</OWNER>
<OWNERTEAM>IT</OWNERTEAM>
<URGENCY>Medium</URGENCY>
<IMPACT>Medium</IMPACT>
<SOURCE>Email</SOURCE>
</INCIDENT>
-->

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:variable name="ebody"/>
<!-- transform to xml fragment -->
<xsl:variable name="params" select="msxsl:node-set($ebody)/tag[@name='INCIDENT']/tag"/>
<xsl:template match="/">
<BusinessObjectList SchemaVersion="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="HierarchicalObjects-1.0.xsd">
<!-- Templates in Abhängigkeit des eMail Betreffs aufrufen -->

<xsl:variable name="Subject" select = "BusinessObjectList/BusinessObject/EmailMessage/Subject"/>
<xsl:choose>
<xsl:when test="contains($Subject,'Incident#')">
<xsl:call-template name="INCIDENT-UPDATE"/>
</xsl:when>

<xsl:when test="contains(translate($Subject,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), 'printer')">
<xsl:call-template name="INCIDENT-KEYWORD-PRINTER"/>
</xsl:when>

<xsl:when test="contains(translate($Subject,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), 'outlook')">
<xsl:call-template name="INCIDENT-KEYWORD-OUTLOOK"/>
</xsl:when>

<xsl:when test="contains($Subject,'Service Request#')">
<xsl:call-template name="SERVICE-REQUEST-UPDATE"/>
</xsl:when>
<xsl:when test="contains($Subject,'Task#')">
<xsl:call-template name="TASK-UPDATE"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="INCIDENT-NEW" />

</xsl:otherwise>
</xsl:choose>
</BusinessObjectList>
</xsl:template>









<xsl:template name="INCIDENT-NEW">
<!--
Erzeugt aus der e-Mail den XML Code zum Aktualisieren Anlage eines neuen Incidents
- Die Attachments werden dem Incident hinzugefügt

Beispielaufruf:
<xsl:call-template name="INCIDENT-NEW" />
-->
<!-- find the profile link recid of the email sender -->
<xsl:variable name="profilelink_recid">

<!-- for each RelatedBusinessObject -->
<xsl:for-each select="BusinessObjectList/BusinessObject/RelatedBusinessObjectList/RelatedBusinessObject/BusinessObject">
<xsl:choose>
<xsl:when test="@Name = 'Employee'">
<xsl:for-each select="./FieldList/Field">
<xsl:choose>
<xsl:when test="@Name = 'RecId'">
<!-- <xsl:value-of select="."/>-->
<xsl:value-of select="'620F9E6687914E61A386572763768870'"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>




<!-- find the profile link category of the email sender -->
<xsl:variable name="profilelink_cat">

<!-- for each RelatedBusinessObject -->
<xsl:for-each select="BusinessObjectList/BusinessObject/RelatedBusinessObjectList/RelatedBusinessObject/BusinessObject">
<xsl:choose>
<xsl:when test="@Name = 'Employee'">
<xsl:value-of select="'Employee'"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>

<!-- for each BusinessObject -->
<xsl:for-each select="BusinessObjectList/BusinessObject">
<!-- Set the BO name -->
<xsl:element name="BusinessObject">
<!-- Set BO Name as 'Incident' -->
<xsl:attribute name="Name">
<xsl:value-of select="'Incident'"/>
</xsl:attribute>

<!-- Set Transaction as 'Insert' -->
<xsl:element name="Transaction">UpdateAdd</xsl:element>

<!--Unique Key List-->
<xsl:element name="UniqueKeyList">
<xsl:element name="UniqueKey">
<xsl:element name="Field">
<xsl:attribute name="Name">
<xsl:value-of select="'IncidentNumber'"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:element>

<!-- Field List -->
<FieldList>
<!-- Fields -->
<xsl:for-each select="EmailMessage/node()">
<xsl:choose>
<!-- Incident.Subject = Email.Subject-->
<xsl:when test="name() = 'Subject'">
<xsl:element name="Field">
<xsl:attribute name="Name">
<xsl:value-of select="'Subject'"/>
</xsl:attribute>
<xsl:attribute name="Type">System.String</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>

<xsl:element name="Field">
<xsl:attribute name="Name">
<xsl:value-of select="'Category'"/>
</xsl:attribute>
<xsl:attribute name="Type">System.String</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>


</xsl:when>

<xsl:when test="name() = 'Body'">



<xsl:variable name="emailbody" method="html" indent="yes" >
<xsl:choose>
<xsl:when test="starts-with(normalize-space(.), '<INCIDENT>')">
<xsl:call-template name=" deleteHtmlTags">
<xsl:with-param name="html" select="@a" />
</xsl:call-template>
<xsl:call-template name="StringToXML">
<!-- remove CRLF -->
<xsl:with-param name="text" select="translate(., '&#xA;', '')" method="html" indent="yes"/>

</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Email body does not contain XML for Incident'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="parameters" select="msxsl:node-set($emailbody)/tag[@name='INCIDENT']/tag" />

<xsl:variable name="symptom" select="$parameters[@name='DESCRIPTION']/text()" />
<xsl:variable name="service" select="$parameters[@name='SERVICE']/text()"/>
<!--<xsl:variable name="category" select="$parameters[@name='CATEGORY']/text()"/>-->

<xsl:variable name="status" select="$parameters[@name='STATUS']/text()"/>

<xsl:variable name="owner" select="$parameters[@name='OWNER']/text()"/>
<xsl:variable name="ownerteam" select="$parameters[@name='OWNERTEAM']/text()"/>

<xsl:variable name="impact" select="$parameters[@name='IMPACT']/text()"/>
<xsl:variable name="urgency" select="$parameters[@name='URGENCY']/text()"/>
<xsl:variable name="source" select="$parameters[@name='SOURCE']/text()"/>



<!-- Symptom -->


<xsl:element name="Field">
<xsl:attribute name="Name">
<xsl:text method="html" indent="yes" match="a" >Symptom</xsl:text>
</xsl:attribute>
<xsl:choose>
<xsl:when test="string-length($symptom) > 0">
<xsl:value-of select="$symptom" disable-output-escaping="yes"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>Default Symptom goes here</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:element>


</xsl:when>
</xsl:choose>
</xsl:for-each>
</FieldList>


</xsl:element>

</xsl:for-each>

</xsl:template>



<xsl:template name="StringToXML">
<xsl:param name="text"/>
<xsl:choose>
<!-- check if $text is a xml fragment -->
<xsl:when test="contains($text, '<')">
<xsl:variable name="tmp1" select="substring-after($text, '<')" />
<xsl:variable name="tmp2" select="substring-after($tmp1, '>')" />
<xsl:variable name="tagName" select="substring-before($tmp1, '>')" />
<xsl:variable name="endTag" select="concat(concat('<', concat('/', $tagName)), '>') " />
<xsl:value-of select="substring-before($text, '<')" />
<!-- create the tag -->
<xsl:element name="tag">
<xsl:attribute name="name"><xsl:value-of select="translate($tagName, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/></xsl:attribute>
<!-- create the children tree -->
<xsl:call-template name="StringToXML">
<xsl:with-param name="text" select="substring-before($tmp2, $endTag)" />
</xsl:call-template>
</xsl:element>
<!-- create the following siblings tree -->
<xsl:call-template name="StringToXML">
<xsl:with-param name="text" select="substring-after($tmp2, $endTag)"/>
</xsl:call-template>
</xsl:when>
<!-- $text is not a xml fragment, so just print the text itsself-->
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$text !=''">
<xsl:value-of select="$text" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Invalid XML. Empty string'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="deleteHtmlTags">
<xsl:param name="html"/>
<xsl:choose>
<xsl:when test="contains($html, '<')">
<xsl:value-of select="substring-before($html, '<')"/>
<!-- Recurse through HTML -->
<xsl:call-template name="deleteHtmlTags">
<xsl:with-param name="html" select="substring-after($html, '>')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$html"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>



</xsl:stylesheet>

TIA.