• No results found

Chapter 9. Analyzing customizations

9.7 Customize DXLMagic

9.7.2 Customizing the Compare process

The compare process internally has three steps: 1. Find two elements to compare

2. Perform the comparison

Chapter 9. Analyzing customizations 169

CompareDXL, the routine used in DXLMagic to compare elements, first tries to find matching elements using the UniversalID of the note. This works well if the custom template was derived from a copy of the original template. If a match is not found it looks for a element with the same alias if the current element has an alias and then with the same name.

Figure 9-24 illustrates the flow used for the comparison routine.

Figure 9-24 Flow of finding the right element

The easiest way to customize the compare process is altering the “Transform to ‘leaner’ XML” step in the flowchart. It uses an XSLT transformation to achieve this. The XSLT file is part of the DXLMagic.jar file.

You can open any JAR file with an extraction utility. Windows Explorer can do this for you after you renamed DXLMagic.jar to DXLMagix.zip.

Navigate to com/ibm/sg/dxlMagic/resources. There you find CompareCleanup.xslt, which is used to simplify the DXL into something more manageable. Example 9-19 shows the code for the CompareCleanup.xslt for your review.

Example 9-19 The simplification stylesheet

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

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:d="http://www.lotus.com/dxl" xmlns="http://www.lotus.com/dxl">

<xsl:output method="xml" indent="yes" xml:space="preserve" /> ‘‘‘‘<xsl:template match="/"><xsl:apply-templates /></xsl:template> <xsl:template match="d:database"> <database> <xsl:apply-templates> <xsl:sort select="name()"/> <xsl:sort select="@name" /> </xsl:apply-templates> </database> </xsl:template>

<!-- Elements we want to suppress but get the decendants, we have them one by one for easier mainenance -->

<xsl:template match="d:run"><xsl:apply-templates /></xsl:template> <xsl:template match="d:table"><xsl:apply-templates /></xsl:template> <xsl:template match="d:tablerow"><xsl:apply-templates /></xsl:template> <xsl:template match="d:tablecell"><xsl:apply-templates /></xsl:template>

<!-- Stuff we want to suppress including any content --> <xsl:template match="d:acl" /> <xsl:template match="d:databaseinfo" /> <xsl:template match="d:launchsettings" /> <xsl:template match="d:helpaboutdocument" /> <xsl:template match="d:helpusingdocument" /> <xsl:template match="d:noteinfo" /> <xsl:template match="d:imageresource" /> <xsl:template match="d:wassignedby" /> <xsl:template match="d:updatedby" /> <xsl:template match="d:revisions" /> <xsl:template match="d:note" /> <xsl:template match="d:tablecolumn" /> <xsl:template match="d:font" /> <xsl:template match="d:border" /> <xsl:template match="d:actionbarstyle" /> <xsl:template match="d:actionbuttonstyle" /> <xsl:template match="d:tablerowstyle" /> <xsl:template match="d:agentdata" /> <xsl:template match="d:rundata" />

<!-- We don't compare RAWITEMS and item not inside the body tag. Duplicate rules to avoid ambigous matches-->

<xsl:template match="d:item[d:rawitemdata]" /> <xsl:template match="d:form/d:item" /> <xsl:template match="d:subform/d:item" /> <xsl:template match="d:form/d:item[d:rawitemdata]" /> <xsl:template match="d:subform/d:item[d:rawitemdata]" />

Chapter 9. Analyzing customizations 171

<!-- Copy everything 1:1 to the result if not specified otherwise --> <xsl:template match="*">

<xsl:variable name="curTagName" select="name()"/> <xsl:element name="{$curTagName}">

<!-- Walk through the attributes --> <xsl:if test="d:noteinfo">

<xsl:attribute name="unid"><xsl:value-of select="d:noteinfo/@unid" /></xsl:attribute> </xsl:if> <xsl:apply-templates select="@*"> <xsl:sort select="name()" /> </xsl:apply-templates> <xsl:apply-templates/> </xsl:element> </xsl:template> <xsl:template match="@*">

<xsl:variable name="curAttName" select="name()"/> <xsl:attribute name="{$curAttName}"><xsl:value-of select="."/></xsl:attribute>

</xsl:template>

</xsl:stylesheet>

Inspecting the simplification stylesheet closer, you can distinguish four sections:

򐂰 The starting section with basic definitions and the root and database template starting the processing. The root template has the selection formula match=”/”. The database template specifies two sort keys for all top level elements: name() and @name. This will sort the resulting XML by element types (<agent ...><form ...><view ...>) and then by the name of the element. The @ sign stands for “Attribute”.

Example 9-20 shows the code for the start section of the XSLT. Example 9-20 The start section

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

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:d="http://www.lotus.com/dxl" xmlns="http://www.lotus.com/dxl">

<xsl:output method="xml" indent="yes" xml:space="preserve" /> <xsl:template match="/"><xsl:apply-templates /></xsl:template> <xsl:template match="d:database"> <database> <xsl:apply-templates> <xsl:sort select="name()"/> <xsl:sort select="@name" /> </xsl:apply-templates> </database> </xsl:template>

򐂰 One section with elements we are not interested in, but need to analyze the content. The template tells the XML processor to look into the child elements (xsl:apply-templates) but doesn’t define any output for the element itself.

Example 9-21 illustrates the section of code for Elements we want to suppress but get the descendants,

Example 9-21 Elements we only check the content

<xsl:template match="d:run"><xsl:apply-templates /></xsl:template> <xsl:template match="d:table"><xsl:apply-templates /></xsl:template> <xsl:template match="d:tablerow"><xsl:apply-templates /></xsl:template> <xsl:template match="d:tablecell"><xsl:apply-templates /></xsl:template>

򐂰 One section with elements or attributes we do not intend to compare and are not

interested in the inner workings. For a customized template updated by and was signed by are definitely different, so stating the obvious does not help us, so we remove these elements (and all the others). As a general rule in XSLT, the more precise the match is, the higher the priority for a template, with match=”*” being the lowest priority. A template that directly ends without a body leads to no output in the result file.

Example 9-22 illustrates how this suppresses the elements. Example 9-22 Suppressing design elements

<xsl:template match="d:wassignedby" /> <xsl:template match="d:updatedby" />

򐂰 The final section with the weak matches match=”*” (any element) and match=”@*” (any attribute) copies the elements 1:1 from the source including all attributes. The attributes get sorted by the attribute name in that process. This eliminates “element has changed” hit for merely changed sequence of attributes which by definition of XML must not be relevant for a comparison result. One specialty that eases the retrieval of matching elements is the treatment of the noteinfo element. When we find an element containing a noteinfo element (which are all top level elements) we pull the @unid attribute element out and store it with the noteid’s parent element. The noteid element itself gets suppressed.

Example 9-23 illustrates the details of this code and how the matching works as described in the paragraph above.

Example 9-23 XSLT 1:1 copy with sorted attributes

<!-- Copy everything 1:1 to the result if not specified otherwise --> <xsl:template match="*">

<xsl:variable name="curTagName" select="name()"/> <xsl:element name="{$curTagName}">

<!-- Walk through the attributes --> <xsl:if test="d:noteinfo">

<xsl:attribute name="unid"><xsl:value-of select="d:noteinfo/@unid" /></xsl:attribute> </xsl:if> <xsl:apply-templates select="@*"> <xsl:sort select="name()" /> </xsl:apply-templates> <xsl:apply-templates/> </xsl:element> </xsl:template> <xsl:template match="@*">

<xsl:variable name="curAttName" select="name()"/>

<xsl:attribute name="{$curAttName}"><xsl:value-of select="."/></xsl:attribute> </xsl:template>

Chapter 9. Analyzing customizations 173

You could add or remove template statements from this stylesheet to tweak your comparison operation. You would need a good understanding of both XSLT and DXL to do that

successfully.