英文:
XML to HTML Conversion using XSL result-document tag in XSL not giving required result
问题
我们已经将 redirect:write(从 XSLT-1.0 使用 Xalan) 替换为 result-document (XSLT-2.0 Saxon 处理器)。
之前使用 redirect:write 用于获取3个输出的HTML,从一个HTML可以通过点击上面的链接导航到另一个HTML。
现在使用 result-document,我们只获取一个单独的HTML,而且在一个HTML中包含了所有3个HTML的数据。此外,点击链接时会显示无法访问,因为其余的HTML没有生成。
以下是XSL文件的代码:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:plm="http://www.plmxml.org/Schemas/PLMXMLSchema"
xmlns:lxslt="http://www.apache.org/xslt"
xmlns:setfile="com.teamcenter.rac.cme.cmereport.CMEReportXalanExtension">
<xsl:key name="Occurrence" match="plm:Occurrence | plm:WorkAreaOccurrence" use="@id"/>
<xsl:key name="Operation" match="plm:Operation" use="@id"/>
<xsl:key name="OperationRevision" match="plm:OperationRevision" use="@id"/>
<xsl:key name="Process" match="plm:Process | plm:Operation" use="@id"/>
<xsl:key name="ProcessOccurrence" match="plm:ProcessOccurrence | plm:Occurrence | plm:WorkAreaOccurrence" use="@id"/>
<xsl:key name="ProcessRevision" match="plm:ProcessRevision | plm:OperationRevision" use="@id"/>
<xsl:key name="ProcessView" match="plm:ProcessView" use="@id"/>
<xsl:key name="ProcOpRevision" match="plm:ProcessRevision | plm:OperationRevision" use="@id"/>
<lxslt:component prefix="setfile" elements="copy" functions="setFile setTcFile getCurrentDir
getCurrentImanFileName getCurrentImanFileNamePrefix getNiceName">
<lxslt:script lang="javaclass" src="com.teamcenter.rac.cme.cmereport.CMEReportXalanExtension"/>
</lxslt:component>
<xsl:output method="html" indent="yes"/>
<xsl:param name="outDir" select="setfile:getCurrentDir(setfile:new())"/>
<xsl:variable name="roid" select="/plm:PLMXML/plm:ProcessView/@rootRefs"/><!-- rootRef instead of prima.. -->
<!-- Assuming that the primaryOccurrenceRef(& NO MULTIPLE ENTRY POINTS) is always a ProcessOccurrence -->
<xsl:variable name="rpoe" select="key('ProcessOccurrence',$roid)"/>
<xsl:variable name="rprid" select="substring-after($rpoe/@instancedRef,'#')"/>
<xsl:variable name="root" select="key('ProcessRevision',$rprid)"/>
<xsl:template match="/">
<xsl:call-template name="genData">
<xsl:with-param name="curProc" select="$root"/>
<xsl:with-param name="occStr" select="$rpoe/@occurrenceRefs"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="genData">
<xsl:param name="curProc"/>
<xsl:param name="occStr">
<html>
<head>
<title>Process: <xsl:value-of select="$curProc/@name"/></title>
</head>
<body BGCOLOR="#FFFFFF" link="#0000FF" vlink="#660066">
<br/>
<!-- Support for Foxfire browser requires specific class="sample" on all table elements -->
<table class="sample"><!-- main table -->
<xsl:call-template name="heading">
<xsl:with-param name="title" select="'Process Report'"/>
</xsl:call-template>
<tr>
<td>
<xsl:variable name="procid">
<xsl:call-template name="cleanId">
<xsl:with-param name="id" select="$curProc/@masterRef"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="proc" select="key('Process',$procid)"/>
<xsl:value-of select="concat($proc/@catalogueId,'/',$curProc/@revision,' - ',$curProc/@name)"/>
</td>
</tr>
<tr><!-- main table:row6::sub level -->
<td>
<hr color="#000000"/>
<table class="sample">
<tr>
<th>Name</th>
</tr>
<xsl:call-template name="createCL">
<xsl:with-param name="chStr" select="$occStr"/>
</xsl:call-template>
</table>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="createCL">
<xsl:param name="chStr"/>
<xsl:variable name="genele" select="key('ProcessOccurrence',$chStr)"/>
<xsl:if test="name($genele)='ProcessOccurrence'">
<xsl:call-template name="creCLext">
<xsl:with-param name="genel" select="$genele"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="creCLext">
<xsl:param name="genel"/>
<xsl:variable name="procid" select="substring-after($genel/@instancedRef,'#')"/>
<xsl:variable name="procele" select="key('ProcOpRevision',$procid)"/><!-- ProcessRevision or OperationRevision -->
<xsl:variable name="pre1" select="substring-after($genel/@predecessorRefs,'#')"/><!--assuming only one id to be present -->
<xsl:variable name="pre2" select="key('ProcessOccurrence',$pre1)"/>
<xsl:variable name="preid" select="substring-after($pre2/@instancedRef,'#')"/>
<xsl:variable name="prele" select="/plm:PLMXML/*[@id=$preid]"/>
<tr>
<td align="center"><a>
<xsl:attribute name="href">
<xsl:value-of select="concat($procid,'.html')"/>
</xsl:attribute>
<xsl:value-of select="$procele/@name"/>
</a></td>
</tr>
<result-document href="concat($procid,'.html')">
<xsl:call-template name="genopr">
<xsl:with-param name="curOpr" select="$procele"/>
<xsl:with-param name="genel"
<details>
<summary>英文:</summary>
We have replaced redirect:write(From XSLT -1.0 with Xalan) with result-document (XSLT-2.0 Saxon processor).
Earlier using redirect:write were used to get 3 output HTMLs, from one HTML we can navigate to another HTML by clicking links available on them.
Now with result-document, we only get single HTML and in single HTML only has all the data of all 3 HTMLs. Also on click of links it says can't reach because remaining HTMLs are not generated.
Below is the Code for XSL File
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:plm="http://www.plmxml.org/Schemas/PLMXMLSchema"
xmlns:lxslt="http://www.apache.org/xslt"
xmlns:setfile ="com.teamcenter.rac.cme.cmereport.CMEReportXalanExtension">
<xsl:key name="Occurrence" match="plm:Occurrence | plm:WorkAreaOccurrence" use="@id"/>
<xsl:key name="Operation" match="plm:Operation" use="@id"/>
<xsl:key name="OperationRevision" match="plm:OperationRevision" use="@id"/>
<xsl:key name="Process" match="plm:Process | plm:Operation" use="@id"/>
<xsl:key name="ProcessOccurrence" match="plm:ProcessOccurrence | plm:Occurrence | plm:WorkAreaOccurrence" use="@id"/>
<xsl:key name="ProcessRevision" match="plm:ProcessRevision | plm:OperationRevision" use="@id"/>
<xsl:key name="ProcessView" match="plm:ProcessView" use="@id"/>
<xsl:key name="ProcOpRevision" match="plm:ProcessRevision | plm:OperationRevision" use="@id"/>
<lxslt:component prefix="setfile" elements="copy" functions="setFile setTcFile getCurrentDir
getCurrentImanFileName getCurrentImanFileNamePrefix getNiceName">
<lxslt:script lang="javaclass" src="com.teamcenter.rac.cme.cmereport.CMEReportXalanExtension"/>
</lxslt:component>
<xsl:output method="html" indent="yes"/>
<xsl:param name="outDir" select="setfile:getCurrentDir(setfile:new())"/>
<xsl:variable name="roid" select="/plm:PLMXML/plm:ProcessView/@rootRefs"/><!-- rootRef instead of prima.. -->
<!-- Assuming that the primaryOccurrenceRef(& NO MULTIPLE ENTRY POINTS) is always a ProcessOccurrence -->
<xsl:variable name="rpoe" select="key('ProcessOccurrence',$roid)"/>
<xsl:variable name="rprid" select="substring-after($rpoe/@instancedRef,'#')"/>
<xsl:variable name="root" select="key('ProcessRevision',$rprid)"/>
<xsl:template match="/">
<xsl:call-template name="genData">
<xsl:with-param name="curProc" select="$root"/>
<xsl:with-param name="occStr" select="$rpoe/@occurrenceRefs"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="genData">
<xsl:param name="curProc"/>
<xsl:param name="occStr"/>
<html>
<head>
<title>Process: <xsl:value-of select="$curProc/@name"/></title>
</head>
<body BGCOLOR="#FFFFFF" link="#0000FF" vlink="#660066">
<br/>
<!-- Support for Foxfire browser requires specific class="sample" on all table elements -->
<table class="sample"><!-- main table -->
<xsl:call-template name="heading">
<xsl:with-param name="title" select="'Process Report'"/>
</xsl:call-template>
<tr>
<td>
<xsl:variable name="procid">
<xsl:call-template name="cleanId">
<xsl:with-param name="id" select="$curProc/@masterRef"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="proc" select="key('Process',$procid)"/>
<xsl:value-of select="concat($proc/@catalogueId,'/',$curProc/@revision,' - ',$curProc/@name)"/>
</td>
</tr>
<tr><!-- main table:row6::sub level -->
<td>
<hr color="#000000"/>
<table class="sample">
<tr>
<th>Name</th>
</tr>
<xsl:call-template name="createCL">
<xsl:with-param name="chStr" select="$occStr"/>
</xsl:call-template>
</table>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="createCL">
<xsl:param name="chStr"/>
<xsl:variable name="genele" select="key('ProcessOccurrence',$chStr)"/>
<xsl:if test="name($genele)='ProcessOccurrence'">
<xsl:call-template name="creCLext">
<xsl:with-param name="genel" select="$genele"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="creCLext">
<xsl:param name="genel"/>
<xsl:variable name="procid" select="substring-after($genel/@instancedRef,'#')"/>
<xsl:variable name="procele" select="key('ProcOpRevision',$procid)"/><!-- ProcessRevision or OperationRevision -->
<xsl:variable name="pre1" select="substring-after($genel/@predecessorRefs,'#')"/><!--assuming only one id to be present -->
<xsl:variable name="pre2" select="key('ProcessOccurrence',$pre1)"/>
<xsl:variable name="preid" select="substring-after($pre2/@instancedRef,'#')"/>
<xsl:variable name="prele" select="/plm:PLMXML/*[@id=$preid]"/>
<tr>
<td align="center"><a>
<xsl:attribute name="href">
<xsl:value-of select="concat($procid,'.html')"/>
</xsl:attribute>
<xsl:value-of select="$procele/@name"/>
</a></td>
</tr>
<result-document href="concat($procid,'.html')">
<xsl:call-template name="genopr">
<xsl:with-param name="curOpr" select="$procele"/>
<xsl:with-param name="genel" select="$genel"/>
</xsl:call-template>
</result-document>
</xsl:template>
<xsl:template name="genopr">
<xsl:param name="curOpr"/>
<xsl:param name="genel"/>
<html>
<head>
<title>Operation: <xsl:value-of select="$curOpr/@name"/></title>
</head>
<body BGCOLOR="#FFFFFF" link="#0000FF" vlink="#660066">
<br/>
<table class="sample"><!-- main table -->
<xsl:call-template name="heading">
<xsl:with-param name="title" select="'Operation Report'"/>
</xsl:call-template>
<tr>
<td>
<xsl:variable name="procid">
<xsl:call-template name="cleanId">
<xsl:with-param name="id" select="$curOpr/@masterRef"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="proc" select="key('Process',$procid)"/>
<xsl:value-of select="concat($proc/@catalogueId,'/',$curOpr/@revision,' - ',$curOpr/@name)"/>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="heading">
<xsl:param name="title"/>
<tr><!-- main table:row1::heading-->
<th>
<div align="left">
</div>
<div align="center"><b><font size="+2"><xsl:value-of select="$title"/></font></b></div><br/>
</th>
</tr>
</xsl:template>
<xsl:template name="cleanId">
<xsl:param name="id"/>
<xsl:choose>
<xsl:when test="contains($id, '#')">
<xsl:value-of select="substring-after($id,'#')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$id"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Below is the the code where we are calling the transformer for conversion from XML to HTML.
{
// 1. Instantiate a TransformerFactory.
javax.xml.transform.TransformerFactory tFactory =(SAXTransformerFactory) SAXTransformerFactory.newInstance();
XslImportResolver myResolve = new XslImportResolver();
tFactory.setURIResolver( myResolve );
// 2. Use the TransformerFactory to process the stylesheet Source and
// generate a Transformer.
javax.xml.transform.Transformer transformer = tFactory.newTransformer
(new javax.xml.transform.stream.StreamSource(xslLocation));
// Add debugging output if it is definded in the Registry.
Registry registry = Registry.getRegistry( this );
// 3. Use the Transformer to perform the transformation and send the
// the output to a Result object.
transformer.transform( new StreamSource( xmlLocation ),
new StreamResult( new FileOutputStream( htmlLocation ) ) );
}
Here is the XML (Partial) input for the Conversion
<?xml version="1.0" encoding="utf-8"?>
<PLMXML xmlns="http://www.plmxml.org/Schemas/PLMXMLSchema"
language="en-us" time="13:52:21" schemaVersion="6">
<Header id="id1" traverseRootRefs="#id6" transferContext="tcm_export"></Header>
<Process id="id20" name="PlantBOp_rediined" subType="Mfg0MEPlantBOP" accessRefs="#id13" catalogueId="002927">
<ApplicationRef application="applicationName" label="AfiRcExBJ_LsEB" version="AfiRcExBJ_LsEB"></ApplicationRef></Process>
<Operation id="id41" name="OP" subType="MEOP" accessRefs="#id13" catalogueId="002929">
<ApplicationRef application="applicationName" label="wvtRcExBJ_LsEB" version="wvtRcExBJ_LsEB"></ApplicationRef></Operation>
<Process id="id45" name="process_station" subType="Mfg0MEProcStatn" accessRefs="#id13" catalogueId="002928">
<ApplicationRef application="applicationName" label="gTqRcExBJ_LsEB" version="gTqRcExBJ_LsEB"></ApplicationRef></Process>
<ProcessRevision id="id18" name="PlantBOp_rediined" subType="Mfg0MEPlantBOPRevision" accessRefs="#id13" masterRef="#id20" revision="A">
<ApplicationRef application="applicationName" label="AfiRcExBJ_LsEB" version="AfpRcExBJ_LsEB"></ApplicationRef>
</ProcessRevision>
<OperationRevision id="id39" name="OP" subType="MEOPRevision" accessRefs="#id13" masterRef="#id41" revision="A">
<ApplicationRef application="applicationName" label="wvtRcExBJ_LsEB" version="wzjRcExBJ_LsEB"></ApplicationRef>
</OperationRevision>
<ProcessRevision id="id43" name="process_station" subType="Mfg0MEProcStatnRevision" accessRefs="#id13" masterRef="#id45" revision="A">
<ApplicationRef application="applicationName" label="gTqRcExBJ_LsEB" version="gXgRcExBJ_LsEB"></ApplicationRef>
</ProcessRevision>
<ProcessView id="id4" ruleRefs="#id2" rootRefs="id6" primaryOccurrenceRef="id8">
<ApplicationRef application="applicationName" label="AjiRcExBJ_LsEB/QkqRjxIVJ_LsEB/AAAAAAAAAAAAAA/BOM/"></ApplicationRef>
<ProcessOccurrence id="id6" instancedRef="#id43" associatedAttachmentRefs="#id23 #id26" occurrenceRefs="id28" parentRef="#id8">
<ApplicationRef application="applicationName" label="AjiRcExBJ_LsEB/gfuRcExBJ_LsEB/"></ApplicationRef>
<Transform id="id5">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</Transform>
<AttributeContext id="id21" attributeName="AO_ID" contextRef="#id8"></AttributeContext></ProcessOccurrence>
<ProcessOccurrence id="id8" instancedRef="#id18" associatedAttachmentRefs="#id11 #id17" occurrenceRefs="id6">
<ApplicationRef application="applicationName" label="AjiRcExBJ_LsEB/"></ApplicationRef>
<Transform id="id7">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</Transform>
<AttributeContext id="id9" attributeName="AO_ID" contextRef="#id8"></AttributeContext></ProcessOccurrence>
<ProcessOccurrence id="id28" instancedRef="#id39" associatedAttachmentRefs="#id31 #id34 #id42" parentRef="#id6" configuredActivityRootRef="#id37">
<ApplicationRef application="applicationName" label="AjiRcExBJ_LsEB/BAqRcExBJ_LsEB/gfuRcExBJ_LsEB/"></ApplicationRef>
<Transform id="id27">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</Transform>
<AttributeContext id="id29" attributeName="AO_ID" contextRef="#id8"></AttributeContext></ProcessOccurrence></ProcessView>
</PLMXML>
we want output file in such a way that user will be able to navigate in it.
In shorter replacement for redirect-write.
</details>
# 答案1
**得分**: 1
<result-document href="concat($procid,'.html')">
</result-document>
应该是
<xsl:result-document href="concat($procid,'.html')">
</xsl:result-document>
<details>
<summary>英文:</summary>
<result-document href="concat($procid,'.html')">
</result-document>
should be
<xsl:result-document href="concat($procid,'.html')">
</xsl:result-document>
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论