Initial publication on git of project from 2006
[OpenWorkBench2MSP_Converter.git] / OWB2MSPConverterB.xsl
1 <?xml version="1.0"?>
2 <!--XSLT 1.0 - http://home.tiscali.de/hillerd - conversion of OpenWorkbench to MS Project -->
3 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
4 <xsl:output method="xml" omit-xml-declaration="no"/>
5 <xsl:output method="xml" cdata-section-elements="Notes"/>
6
7 <xsl:key name="KeyTaskwID" match="Task" use="@wID"/> <!-- Task wID key -->
8 <xsl:key name="KeyBaseCalName" match="BaseCalendars/Calendar" use="@name"/> <!-- Calendar name key -->
9 <xsl:key name="KeyDepUID" match="Dependency" use="@successorUID"/> <!-- Dependency successor UID key-->
10 <xsl:key name="KeyDepID" match="Dependency" use="@successorID"/> <!-- Dependency successor ID key-->
11 <xsl:key name="KeyPoolRes" match="PoolResource" use="@resourceId"/> <!-- Poolresource ID key -->
12
13 <!-- ****************************************************************** start with WORKBENCH_PROJECT **************** -->
14 <xsl:template match="/WORKBENCH_PROJECT">
15 <xsl:apply-templates select="Projects/Project"/> <!-- insert all Projects/Project -->
16 </xsl:template>
17
18 <!-- ****************************************************************** PROJECT ************************************* -->
19 <xsl:template match="Project">
20 <Project xmlns="http://schemas.microsoft.com/project">
21 <Name><xsl:value-of select="@name"/></Name>
22 <StartDate><xsl:value-of select="@start"/></StartDate>
23 <FinishDate><xsl:value-of select="@finish"/></FinishDate>
24 <CalendarUID> <!-- Project Calendar is "Standard" -->
25 <xsl:value-of select='key("KeyBaseCalName", "Standard")/@sID'/>
26 </CalendarUID>
27 <MinutesPerDay>480</MinutesPerDay> <!-- 8h / day -->
28 <HonorConstraints>0</HonorConstraints> <!-- Schedule by task dependencies, not by constraints -->
29 <WeekStartDay>1</WeekStartDay> <!-- week starts on Monday -->
30 <MicrosoftProjectServerURL>0</MicrosoftProjectServerURL> <!-- Project was not generated by MS -->
31 <Autolink>0</Autolink> <!-- Do not autolink inserted tasks -->
32 <ProjectExternallyEdited>1</ProjectExternallyEdited> <!-- Project was externally edited -->
33
34 <Calendars>
35 <xsl:apply-templates select='//BaseCalendars/Calendar'/> <!-- Basecalendars -->
36 <!-- Resource Calendars -->
37 <xsl:apply-templates select="//PoolResource[Calendar]" mode="ResourceCal"/>
38 </Calendars>
39 <Tasks>
40 <xsl:apply-templates select="Tasks/Task"/> <!-- insert all Task(s) -->
41 </Tasks>
42 <Resources>
43 <xsl:apply-templates select="//PoolResource"/> <!-- insert all PoolResource(s) -->
44 </Resources>
45 <Assignments>
46 <xsl:apply-templates select=".//Assignment"/> <!-- insert all Assignment(s) anywhere below -->
47 </Assignments>
48 </Project>
49 </xsl:template>
50
51 <!-- ****************************************************************** Calendar **************************** -->
52 <xsl:template match="Calendar">
53 <Calendar>
54 <UID><xsl:value-of select="@sID"/></UID>
55 <Name><xsl:value-of select="@name"/></Name>
56 <IsBaseCalendar>1</IsBaseCalendar> <!-- all are baseCalendars -->
57 <BaseCalendarUID> <!-- use -1 if has no basecalendar -->
58 <xsl:choose>
59 <xsl:when test='count(@baseCalendar)>0'>
60 <xsl:value-of select='key("KeyBaseCalName", @baseCalendar)/@sID'/>
61 </xsl:when>
62 <xsl:otherwise>-1</xsl:otherwise>
63 </xsl:choose>
64 </BaseCalendarUID>
65 <Weekdays>
66 <xsl:apply-templates select="Days/Day[@dayOfWeek]"/> <!-- insert Day with values from MON to SUN -->
67 <xsl:apply-templates select='Days/Day[@start]' mode='startfinish'/> <!-- insert exceptions -->
68 </Weekdays>
69 </Calendar>
70 </xsl:template>
71
72 <!-- ****************************************************************** Calendar/Days/Day (MON-SUN) ***************** -->
73 <xsl:template match="Day">
74 <Weekday>
75 <DayType>
76 <xsl:choose>
77 <xsl:when test='@dayOfWeek="SUN"'>1</xsl:when>
78 <xsl:when test='@dayOfWeek="MON"'>2</xsl:when>
79 <xsl:when test='@dayOfWeek="TUE"'>3</xsl:when>
80 <xsl:when test='@dayOfWeek="WED"'>4</xsl:when>
81 <xsl:when test='@dayOfWeek="THU"'>5</xsl:when>
82 <xsl:when test='@dayOfWeek="FRI"'>6</xsl:when>
83 <xsl:when test='@dayOfWeek="SAT"'>7</xsl:when>
84 <xsl:otherwise>0</xsl:otherwise>
85 </xsl:choose>
86 </DayType>
87 <DayWorking>
88 <xsl:choose>
89 <xsl:when test='@isWorkDay="true"'>1</xsl:when>
90 <xsl:otherwise>0</xsl:otherwise>
91 </xsl:choose>
92 </DayWorking>
93 <WorkingTimes>
94 <xsl:apply-templates select="Shifts/Shift"/> <!-- insert working time; MSP only allows up to 5 -->
95 </WorkingTimes>
96 </Weekday>
97 </xsl:template>
98
99 <!-- ****************************************************************** Calendar/Days/Day (with startfinish data) *** -->
100 <!-- *** can come from Basecalendar and Resourcecalendar ************************************************************ -->
101 <xsl:template match="Day" mode="startfinish">
102 <WeekDay>
103 <DayType>0</DayType>
104 <DayWorking>
105 <xsl:choose>
106 <xsl:when test='@isWorkDay="true"'>1</xsl:when>
107 <xsl:otherwise>0</xsl:otherwise>
108 </xsl:choose>
109 </DayWorking>
110 <TimePeriod>
111 <FromDate><xsl:value-of select='concat(@start,"T00:00:00")'/></FromDate>
112 <ToDate> <!-- if finish not given provide start -->
113 <xsl:choose>
114 <xsl:when test='count(@finish)>0'><xsl:value-of select='concat(@finish,"T23:59:00")'/></xsl:when>
115 <xsl:otherwise><xsl:value-of select='concat(@start,"T23:59:00")'/></xsl:otherwise>
116 </xsl:choose>
117 </ToDate>
118 </TimePeriod>
119 <xsl:if test='@isWorkDay="true"'> <!-- exceptional working time has standard time -->
120 <WorkingTimes>
121 <WorkingTime>
122 <FromTime>08:00:00</FromTime>
123 <ToTime>12:00:00</ToTime>
124 </WorkingTime>
125 <WorkingTime>
126 <FromTime>13:00:00</FromTime>
127 <ToTime>17:00:00</ToTime>
128 </WorkingTime>
129 </WorkingTimes>
130 </xsl:if>
131 </WeekDay>
132 </xsl:template>
133
134 <!-- ****************************************************************** Calendar/Days/Day/Shifts/Shift ****** -->
135 <xsl:template match="Shift">
136 <WorkingTime>
137 <FromTime><xsl:value-of select="@start"/></FromTime>
138 <ToTime><xsl:value-of select="@finish"/></ToTime>
139 </WorkingTime>
140 </xsl:template>
141
142 <!-- ****************************************************************** Calendar of PoolResource (ResourceCal) ****** -->
143 <xsl:template match="PoolResource" mode="ResourceCal">
144 <Calendar>
145 <UID><xsl:value-of select="@sID+100"/></UID> <!-- Calendar UID is 100 + resource UID -->
146 <Name><xsl:value-of select="@fullName"/></Name> <!-- Calendarname is resource name -->
147 <IsBaseCalendar>0</IsBaseCalendar> <!-- not a baseCalendar -->
148 <BaseCalendarUID>
149 <xsl:value-of select='key("KeyBaseCalName", Calendar/@baseCalendar)/@sID'/>
150 </BaseCalendarUID>
151 <WeekDays>
152 <xsl:apply-templates select='Calendar/Days/Day[@start]' mode='startfinish'/> <!-- insert exceptions -->
153 </WeekDays>
154 </Calendar>
155 </xsl:template>
156
157 <!-- ****************************************************************** Task ************************************ -->
158 <xsl:template match="Task">
159 <Task>
160 <UID><xsl:value-of select="@sID"/></UID> <!-- UID is sequential number -->
161 <ID><xsl:value-of select='position()'/></ID> <!-- ID is sequential number -->
162 <Name><xsl:value-of select="@name"/></Name>
163 <Type>0</Type> <!-- fixed units, necessary because OWB does not exp. dur.-->
164 <OutlineLevel><xsl:value-of select="@outlineLevel"/></OutlineLevel>
165 <Start><xsl:value-of select="@start"/></Start>
166 <Finish><xsl:value-of select="@finish"/></Finish>
167 <Milestone>
168 <xsl:choose>
169 <xsl:when test='@milestone="true"'>1</xsl:when>
170 <xsl:otherwise>0</xsl:otherwise>
171 </xsl:choose>
172 </Milestone>
173 <Summary>
174 <xsl:choose>
175 <xsl:when test='@summary="true"'>1</xsl:when>
176 <xsl:otherwise>0</xsl:otherwise>
177 </xsl:choose>
178 </Summary>
179 <Critical>
180 <xsl:choose>
181 <xsl:when test='@critical="true"'>1</xsl:when>
182 <xsl:otherwise>0</xsl:otherwise>
183 </xsl:choose>
184 </Critical>
185 <FixedCostAccrual>2</FixedCostAccrual> <!-- Prorated, costs accrue as work is scheduled/done -->
186 <PercentComplete><xsl:value-of select="@percComp*100"/></PercentComplete> <!-- OWB:0..1, MSP:0..100 -->
187
188 <xsl:if test='@percComp &gt; 0'> <!-- if started, set actual start date -->
189 <ActualStart><xsl:value-of select="@start"/></ActualStart>
190 </xsl:if>
191
192 <CalendarUID>-1</CalendarUID> <!-- no task calendar -->
193
194 <xsl:apply-templates select="Constraints/Constraint[1]"/> <!-- take only first constraint -->
195 <Notes> <!-- MSP only allows 1 note, OWB more -->
196 <xsl:for-each select='Notes/Note'>
197 <xsl:value-of select='@content'/>
198 <xsl:if test='position() != last()'><xsl:text>&#xA;</xsl:text></xsl:if>
199 </xsl:for-each>
200 </Notes>
201 <xsl:choose> <!-- dependencies with UID or taskID -->
202 <xsl:when test='count(@UID)>0'><xsl:apply-templates select='key("KeyDepUID",@UID)'/> </xsl:when>
203 <xsl:otherwise> <xsl:apply-templates select='key("KeyDepID",@taskID)'/></xsl:otherwise>
204 </xsl:choose>
205 </Task>
206 </xsl:template>
207
208 <!-- ****************************************************************** Task/Constraint ************************** -->
209 <xsl:template match="Constraint">
210 <!-- type sequence OWB: mso, snet, snlt, mfo, fnet, fnlt; 0:none, 1:alap, 2:asap (not possible) -->
211 <ConstraintType>
212 <xsl:value-of select='translate(@type, "678534012", "245367010")'/>
213 </ConstraintType>
214
215 <xsl:if test='@type>"2"'> <!-- time only-if needed (not for none, asap, alap) -->
216 <ConstraintDate>
217 <xsl:value-of select="@time"/>
218 </ConstraintDate>
219 </xsl:if>
220 </xsl:template>
221
222 <!-- ****************************************************************** Task/Dependency ***************************** -->
223 <!-- *** selected is that dependency, where the successorID is equal to the current taskID ************************** -->
224 <xsl:template match="Dependency">
225 <PredecessorLink> <!-- take predID, find wID and output sID -->
226 <xsl:choose> <!-- can come from taskID or UID -->
227 <xsl:when test='count(@predecessorID)>0'>
228 <xsl:apply-templates select='key("KeyTaskwID",@predecessorID)' mode="Taskpredecessor"/>
229 </xsl:when>
230 <xsl:otherwise>
231 <xsl:apply-templates select='key("KeyTaskwID",@predecessorUID)' mode="Taskpredecessor"/>
232 </xsl:otherwise>
233 </xsl:choose>
234 <Type>
235 <xsl:value-of select='translate(@startFinishType, "0123", "1302")'/> <!-- FS, SS FF SF -->
236 </Type>
237 <CrossProject>0</CrossProject> <!-- no external project -->
238 <CrossProjectName/> <!-- empty string-->
239 <LinkLag>
240 <xsl:choose> <!-- 1 day has 4800 tenth of minute -->
241 <xsl:when test='@lagType="0"'><xsl:value-of select="@lag*4800"/></xsl:when> <!-- days -->
242 <xsl:when test='@lagType="1"'><xsl:value-of select="@lag"/></xsl:when> <!-- % -->
243 </xsl:choose>
244 </LinkLag>
245 <LagFormat>
246 <xsl:choose>
247 <xsl:when test='@lagType="0"'>7</xsl:when> <!-- days -->
248 <xsl:when test='@lagType="1"'>19</xsl:when> <!-- % -->
249 <xsl:otherwise>53</xsl:otherwise> <!-- null-->
250 </xsl:choose>
251 </LagFormat>
252 </PredecessorLink>
253 </xsl:template>
254
255 <!-- ****************************************************************** Task (Taskpredecessor) ********************** -->
256 <!-- *** selected is that task whose PredecessorID is equal to the current sID ************************************** -->
257 <xsl:template match="Task" mode="Taskpredecessor">
258 <PredecessorUID>
259 <xsl:value-of select="@sID"/>
260 </PredecessorUID>
261 </xsl:template>
262
263 <!-- ****************************************************************** PoolResource ******************************** -->
264 <xsl:template match="PoolResources/PoolResource">
265 <Resource> <!-- Days exception to baseCalendar are not included -->
266 <UID><xsl:value-of select="@sID"/></UID>
267 <ID><xsl:value-of select="position()"/></ID>
268 <Name><xsl:value-of select="@fullName"/></Name>
269 <Type> <!-- Work/Equipment/Material/Expenses to Material/Work -->
270 <xsl:value-of select='translate(@resourceType, "0123", "1100")'/>
271 </Type>
272 <Initials><xsl:value-of select="@resourceId"/></Initials> <!-- OWB uses initials as UID when reading MSP XML -->
273 <CalendarUID> <!-- use resource calendar -->
274 <xsl:value-of select="@sId"/><xsl:value-of select="@sID+100"/>
275 </CalendarUID>
276 <Notes> <!-- MSP only allows 1 note, OWB more -->
277 <xsl:for-each select='Notes/Note'>
278 <xsl:value-of select='@content'/>
279 <xsl:if test='position() != last()'><xsl:text>&#xA;</xsl:text></xsl:if>
280 </xsl:for-each>
281 </Notes>
282 </Resource>
283 </xsl:template>
284
285 <!-- ****************************************************************** Assignment ********************************** -->
286 <xsl:template match="Assignment">
287 <Assignment>
288 <UID><xsl:value-of select="position()"/></UID>
289 <TaskUID><xsl:value-of select="../../@sID"/></TaskUID>
290 <xsl:apply-templates select='key("KeyPoolRes",@resourceID)' mode='PoolResAss'/> <!-- ResourceID -->
291 <Finish><xsl:value-of select="../../@finish"/></Finish>
292 <Start><xsl:value-of select="../../@start"/></Start>
293 </Assignment>
294 </xsl:template>
295
296 <!-- ****************************************************************** PoolResource (Assignment) ******************* -->
297 <xsl:template match="PoolResource" mode='PoolResAss'>
298 <ResourceUID>
299 <xsl:value-of select="@sID"/>
300 </ResourceUID>
301 </xsl:template>
302
303 </xsl:stylesheet>