It's been a while since I've working with XML and XSLT. I know need to do a one off job translating one XML to another. The structure of the XML remains the same, but I need to move some values around. Not the toughest job.
Now that I'm almost done I run into the problem that an attribute uses a forward slash in its name (I can't control the naming) and I need to do a value-of an element with this specific attribute. When running this with msxsl version 2.0 I get the error:
Error occurred while compiling stylesheet 'Update.xsl'.
Code: 0x80004005
Expected token 'EOF' found 'NAME'.
./Dossier -->number <--/ name
Here is an example of my input xml (which is auto generated by some application)
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<import>
<node action="create" type="document">
<acl basegroup="DefaultGroup" permissions="111011000"></acl>
<acl baseowner="a189suv" permissions="111111111"></acl>
<acl permissions="111011000" standard="world"></acl>
<category name="Livelink Categories:Taxonomy:Common">
<attribute name="Editor (Creator/Author)"><![CDATA[Gregor de Graaf]]></attribute>
<attribute clear="true" name="Editor (Creator/Author) - User"></attribute>
<attribute name="Entity"><![CDATA[719 - TNT Head Office B.V.]]></attribute>
<attribute name="Country"><![CDATA[Netherlands]]></attribute>
<attribute name="Division"><![CDATA[Corporate]]></attribute>
<attribute name="Document Type"><![CDATA[Report]]></attribute>
<attribute name="Date"><![CDATA[20080819]]></attribute>
<attribute name="Original Name"><![CDATA[Taxonomy description 1.1.pdf]]></attribute>
<attribute clear="true" name="Title"></attribute>
<attribute name="Subject"><![CDATA[Taxonomy description]]></attribute>
<attribute name="Status"><![CDATA[Draft]]></attribute>
<attribute name="Language"><![CDATA[English]]></attribute>
<attribute name="Security Classification"><![CDATA[Internal]]></attribute>
<attribute name="Function"><![CDATA[Accounting]]></attribute>
<attribute clear="true" name="Original Entity"></attribute>
</category>
<category name="Livelink Categories:Taxonomy:Report:Report">
<attribute name="Sub Document Type"><![CDATA[Not Applicable]]></attribute>
</category>
<category name="Livelink Categories:Optional:Dossier">
<attribute name="Project Executive"><![CDATA[Gerrit Jan van Donk]]></attribute>
<attribute name="Project number / name"><![CDATA[Group Document Management Project]]></attribute>
<attribute name="Project Sponsor"><![CDATA[Henk van Dalen]]></attribute>
</category>
<created><![CDATA[20081017150144]]></created>
<createdby><![CDATA[a189suv]]></createdby>
<description clear="true"></description>
<file><![CDATA[d:\object_exporter\control\export_test_20100219141220\20100219141220132446\0000000002]]></file>
<location><![CDATA[Enterprise:Temporary_Upload_Staging_Area]]></location>
<mime><![CDATA[application/pdf]]></mime>
<modified><![CDATA[20100128110401]]></modified>
<title><![CDATA[Taxonomy description]]></title>
</node>
</import>
Here is an example of the xml I would like as output
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<import>
<node action="update" type="document">
<location>Enterprise:Livelink (Technical) Documentation:Categories:Customised_Categories.doc</location>
<title></title>
</node>
<node action="update" type="document">
<location>Enterprise:Temporary_Upload_Staging_Area:Taxonomy description</location>
<title>Taxonomy description</title>
<created>20080819</created>
<category name="Livelink Categories:Taxonomy:Common">
<attribute name="Function">Accounting</attribute>
<attribute name="Country">Netherlands</attribute>
<attribute name="Region / Business unit" />
<attribute name="Division">Corporate</attribute>
<attribute name="Document date">20080819</attribute>
<attribute name="Title">Taxonomy description</attribute>
<attribute name="Retention date">20150819</attribute>
<attribute name="Document type">Legal report</attribute>
</category>
<category name="Livelink Categories:Taxonomy:Legal report:Legal report">
<attribute name="Legal entity">719 - TNT Head Office B.V.</attribute>
<attribute name="Sub document type">Not Applicable</attribute>
</category>
<category name="Livelink Categories:Optional:Dossier">
<attribute name="Dossier number / name" >Group Document Management Project</attribute>
<attribute name="Security classification">Internal</attribute>
</category>
</node>
</import>
And finally the xslt:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Description:
This XSLT stylesheet is intended to use the Livelink object importer to update the Livelink categories due to the changed
taxonomy.
Author: Bas van der Meijden
Date: 22 February 2010
Version: 0.1
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" standalone="yes" omit-xml-declaration="no" />
<xsl:template match="/">
<import>
<xsl:apply-templates />
</import>
</xsl:template>
<xsl:template match="node">
<xsl:element name="node">
<xsl:attribute name="action">update</xsl:attribute>
<xsl:attribute name="type"><xsl:value-of select="@type" /></xsl:attribute>
<xsl:element name="location"><xsl:value-of select="concat(location,':',title)" /></xsl:element>
<xsl:element name="title"><xsl:value-of select="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Subject']" /></xsl:element>
<!--
Check if the Document Date contains a value, if not, we won't add the created element
-->
<xsl:if test= "string(number(category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Date']))!='NaN'">
<xsl:element name="created">
<!--
format: yyyymmddhhmmss, only yyyymmdd can be used as well
-->
<xsl:value-of select="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Date']" />
</xsl:element>
</xsl:if>
<!--
check if a the common category exists, if not, we won't add categories.
Use count of boolean. First test out
-->
<xsl:if test="boolean(category[@name='Livelink Categories:Taxonomy:Common'])" >
<xsl:element name="category">
<xsl:attribute name="name">Livelink Categories:Taxonomy:Common</xsl:attribute>
<xsl:element name="attribute">
<xsl:attribute name="name">Function</xsl:attribute>
<xsl:value-of select="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Function']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Country</xsl:attribute>
<xsl:value-of select="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Country']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Region / Business unit</xsl:attribute>
<!--
Here the Region / Business unit must come. This will be the last main challenge!!
-->
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Division</xsl:attribute>
<xsl:value-of select="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Division']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Document date</xsl:attribute>
<xsl:value-of select="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Date']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Title</xsl:attribute>
<xsl:value-of select="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Subject']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Retention date</xsl:attribute>
<!--
Here the retention date must be calculated. This has been defaulted to Document date + 7 years.
A value is only provided when the Document date attribute has a value
-->
<xsl:if test="string(number(category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Date']))!='NaN'">
<xsl:value-of select="concat(string(number(substring(category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Date'],1,4))+7),substring(category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Date'],5))" />
</xsl:if>
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Document type</xsl:attribute>
<!--
The document types need to be translated to the new document types
Function below is for testing purposes
-->
<xsl:choose>
<xsl:when test="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Document Type'] = 'Agreement'">Agreement / contract</xsl:when>
<xsl:when test="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Document Type'] = 'Correspondence'">Legal correspondence</xsl:when>
<xsl:when test="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Document Type'] = 'Power of Attorney'">Legal correspondence</xsl:when>
<xsl:when test="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Document Type'] = 'Report'">Legal report</xsl:when>
<xsl:when test="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Document Type'] = 'Presentation'">Presentation</xsl:when>
<xsl:when test="category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Document Type'] = 'Resolution'">Legal correspondence</xsl:when>
<xsl:otherwise>
ERROR
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:element>
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Agreement:Agreement']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Correspondence:Correspondence']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Power of Attorney:Power of Attorney']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Report:Report']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Resolution:Resolution']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Optional:Dossier']" />
</xsl:if>
</xsl:element>
</xsl:template>
<xsl:template match="category[@name='Livelink Categories:Taxonomy:Agreement:Agreement']">
<xsl:element name="category">
<xsl:attribute name="name">Livelink Categories:Taxonomy:Agreement / contract:Agreement / contract</xsl:attribute>
<xsl:element name="attribute">
<xsl:attribute name="name">Legal entity</xsl:attribute>
<xsl:value-of select="../category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Entity']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Contracting party</xsl:attribute>
<!--
The statement below contatenates 3 values. Without the comma's, the strings are concatenated without any readable interpunction or white space
With the comma's inserted, the comma's are displayed regardless of the fact if any of these values actually exists. This can be tested out
before creating the string
-->
<xsl:value-of select="attribute[@name='Party 1']" />, <xsl:value-of select="attribute[@name='Party 2']" />, <xsl:value-of select="attribute[@name='External Party']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Sub document type</xsl:attribute>
<xsl:value-of select="attribute[@name='Sub Document Type']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Start date</xsl:attribute>
<xsl:value-of select="attribute[@name='Start Date']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Expiration date</xsl:attribute>
<xsl:value-of select="attribute[@name='Expiration Date']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Notice period</xsl:attribute>
<xsl:value-of select="attribute[@name='Notice']" />
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="category[@name='Livelink Categories:Taxonomy:Correspondence:Correspondence']">
<xsl:element name="category">
<xsl:attribute name="name">Livelink Categories:Taxonomy:Legal correspondence:Legal correspondence</xsl:attribute>
<xsl:element name="attribute">
<xsl:attribute name="name">Legal entity</xsl:attribute>
<xsl:value-of select="../category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Entity']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Receiver</xsl:attribute>
<xsl:value-of select="attribute[@name='Receiver']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Sender</xsl:attribute>
<xsl:value-of select="attribute[@name='Sender']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Sub document type</xsl:attribute>
<xsl:value-of select="attribute[@name='Sub Document Type']" />
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="category[@name='Livelink Categories:Taxonomy:Power of Attorney:Power of Attorney']">
<xsl:element name="category">
<xsl:attribute name="name">Livelink Categories:Taxonomy:Legal correspondence:Legal correspondence</xsl:attribute>
<xsl:element name="attribute">
<xsl:attribute name="name">Legal entity</xsl:attribute>
<xsl:value-of select="../category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Entity']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Receiver</xsl:attribute>To whom it may concern</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Sender</xsl:attribute>
<xsl:value-of select="attribute[@name='Approver']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Sub document type</xsl:attribute>Power of Attorney</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="category[@name='Livelink Categories:Taxonomy:Report:Report']">
<xsl:element name="category">
<xsl:attribute name="name">Livelink Categories:Taxonomy:Legal report:Legal report</xsl:attribute>
<xsl:element name="attribute">
<xsl:attribute name="name">Legal entity</xsl:attribute>
<xsl:value-of select="../category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Entity']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Sub document type</xsl:attribute>
<xsl:value-of select="attribute[@name='Sub Document Type']" />
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="category[@name='Livelink Categories:Taxonomy:Resolution:Resolution']">
<xsl:element name="category">
<xsl:attribute name="name">Livelink Categories:Taxonomy:Legal correspondence:Legal correspondence</xsl:attribute>
<xsl:element name="attribute">
<xsl:attribute name="name">Legal entity</xsl:attribute>
<xsl:value-of select="../category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Entity']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Receiver</xsl:attribute>To whom it may concern</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Sender</xsl:attribute>
<xsl:value-of select="attribute[@name='Decider']" />
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Sub document type</xsl:attribute>Resolution</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="category[@name='Livelink Categories:Optional:Dossier']">
<xsl:element name="category">
<xsl:attribute name="name">Livelink Categories:Optional:Dossier</xsl:attribute>
<xsl:element name="attribute">
<xsl:attribute name="name">Dossier number / name</xsl:attribute>
<!-- Statement belows hangs on the '/' character in the select clause. Need a way to figure out how to solve this -->
<xsl:value-of select="Dossier number / name" />
<!-- ERROR -->
</xsl:element>
<xsl:element name="attribute">
<xsl:attribute name="name">Security classification</xsl:attribute>
<xsl:value-of select="../category[@name='Livelink Categories:Taxonomy:Common']/attribute[@name='Security Classification']" />
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Where my issues is the following statement
Code:
<xsl:value-of select="./Dossier number / name" />
On a side note: Doesn anyone know why calling specific templates works
Code:
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Agreement:Agreement']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Correspondence:Correspondence']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Power of Attorney:Power of Attorney']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Report:Report']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Taxonomy:Resolution:Resolution']" />
<xsl:apply-templates select="category[@name='Livelink Categories:Optional:Dossier']" />
and just calling <xsl:apply-templates /> will print all child-element values contained in the current node?
Any suggestion with the forward slash in the the attribute value is highlyl appreciated. My current workaround would be to search and replace in the original xml file then do the xslt translation and then search and replace back in the ouput xml file.